MT4脚本,MT4脚本默认使用unicode,utf-16编码,而目前dll代码用的字符集是ansi,所以下面的代码需要做一次字符集转换
#import "HttpPost.dll"
int HttpPost(char &url[], char &headers[], char &body[], char &response[], int responseSize);
#import
void OnStart()
{
// 定义测试的 URL
string url = "http://127.0.0.1:8000/api/ainance/mt/receive_order";
// 定义测试的 JSON 数据
string jsonData = "{\"symbol\": \"EURUSD\", \"lot_size\": 1.5, \"price\": 1.12345, \"order_type\": \"BUY\"}";
// 定义测试的请求头
string headers = "Content-Type: application/json\r\n";
// 转换字符串为 ANSI 编码
char urlAnsi[];
char headersAnsi[];
char bodyAnsi[];
StringToCharArray(url, urlAnsi); // URL 转换为 ANSI
StringToCharArray(headers, headersAnsi); // 请求头转换为 ANSI
StringToCharArray(jsonData, bodyAnsi); // JSON 数据转换为 ANSI
// 响应数据
char response[8192];
int responseSize = ArraySize(response);
// 调用 DLL 中的 HttpPost 函数
int result = HttpPost(urlAnsi, headersAnsi, bodyAnsi, response, responseSize);
// 处理返回结果
if (result == 0) // 假设 0 表示请求成功
{
string responseText = CharArrayToString(response);
Print("请求成功,服务器返回:", responseText);
}
else
{
PrintFormat("请求失败!错误代码:%d", result);
}
}
对应的dll的代码:下面的代码用ansi字符集
#include <windows.h>
#include <string>
#include <iostream>
#include <wininet.h>
#include <fstream>
// 调试日志函数
void WriteLog(const std::string& message) {
std::string logFileName = "chriszhao_Debug.log";
std::ofstream logFile(logFileName, std::ios::app);
if (logFile.is_open()) {
logFile << message << std::endl;
logFile.close();
}
}
// 导出函数声明
extern "C" __declspec(dllexport) int HttpPost(const char* url, const char* headers, const char* body, char* response, int responseSize);
// HTTP POST 函数实现
extern "C" __declspec(dllexport) int HttpPost(const char* url, const char* headers, const char* body, char* response, int responseSize) {
WriteLog("HttpPost called with parameters:");
WriteLog("URL: " + std::string(url));
WriteLog("Headers: " + std::string(headers));
WriteLog("Body: " + std::string(body));
if (!url || strlen(url) == 0) {
WriteLog("Error: URL is empty or null!");
return -1;
}
if (std::string(url).find("http://") != 0 && std::string(url).find("https://") != 0) {
WriteLog("Error: URL must start with http:// or https://");
return -1;
}
// 打开 Internet 会话
HINTERNET hInternet = InternetOpen("MT4_HTTP_Client", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (!hInternet) {
WriteLog("Error: InternetOpen failed! Error code: " + std::to_string(GetLastError()));
return -1;
}
// 解析 URL
URL_COMPONENTS urlComponents = {0};
char scheme[16] = {0};
char hostName[256] = {0};
char urlPath[1024] = {0};
char extraInfo[256] = {0};
urlComponents.dwStructSize = sizeof(urlComponents);
urlComponents.lpszScheme = scheme;
urlComponents.dwSchemeLength = sizeof(scheme);
urlComponents.lpszHostName = hostName;
urlComponents.dwHostNameLength = sizeof(hostName);
urlComponents.lpszUrlPath = urlPath;
urlComponents.dwUrlPathLength = sizeof(urlPath);
urlComponents.lpszExtraInfo = extraInfo;
urlComponents.dwExtraInfoLength = sizeof(extraInfo);
if (!InternetCrackUrl(url, strlen(url), 0, &urlComponents)) {
WriteLog("Error: InternetCrackUrl failed! URL: " + std::string(url) + ", Error code: " + std::to_string(GetLastError()));
InternetCloseHandle(hInternet);
return -2;
}
WriteLog("InternetCrackUrl succeeded!");
WriteLog("Scheme: " + std::string(urlComponents.lpszScheme ? urlComponents.lpszScheme : "NULL"));
WriteLog("HostName: " + std::string(urlComponents.lpszHostName ? urlComponents.lpszHostName : "NULL"));
WriteLog("UrlPath: " + std::string(urlComponents.lpszUrlPath ? urlComponents.lpszUrlPath : "NULL"));
WriteLog("Port: " + std::to_string(urlComponents.nPort));
// 创建连接
HINTERNET hConnect = InternetConnect(hInternet, urlComponents.lpszHostName, urlComponents.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (!hConnect) {
WriteLog("Error: InternetConnect failed! Error code: " + std::to_string(GetLastError()));
InternetCloseHandle(hInternet);
return -3;
}
// 打开 POST 请求
HINTERNET hRequest = HttpOpenRequest(hConnect, "POST", urlComponents.lpszUrlPath, NULL, NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, 0);
if (!hRequest) {
WriteLog("Error: HttpOpenRequest failed! Error code: " + std::to_string(GetLastError()));
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return -4;
}
// 发送请求
BOOL result = HttpSendRequest(hRequest, headers, strlen(headers), (LPVOID)body, strlen(body));
if (!result) {
WriteLog("Error: HttpSendRequest failed! Error code: " + std::to_string(GetLastError()));
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return -5;
}
// 读取响应
DWORD bytesRead = 0;
result = InternetReadFile(hRequest, response, responseSize - 1, &bytesRead);
if (!result) {
WriteLog("Error: InternetReadFile failed! Error code: " + std::to_string(GetLastError()));
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return -6;
}
response[bytesRead] = '\0';
WriteLog("Response: " + std::string(response));
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return 0;
}
这个dll文件的编译方式为:
g++ -shared -o HttpPost.dll HttpPost.cpp -lwininet "-Wl,--out-implib,HttpPost.lib”
网友评论