前提・実現したいこと
MQL4からDLLを用いて、LineNotifyのAPIを叩くプログラムを作成しています。
インジケーターからWebRequest関数を用いることが不可能だったので、DLLを使おうと考えました。
Windows10を使用しているので、MinGW(32bit)を導入しg++コンパイラを用いてc++のプログラムをDLL化しようと試みました。LineNotifyのAPIを叩くために、libcurl(32bit)をインストールしました。
C++単体のプログラムではlibcurlの関数を使って、LineNotifyにPOSTリクエストを送ることができました。また、libcurlの関数を使用せずにMQL4からDLLを使うこともできました。(適当な整数値を返すだけの関数を使用)
使用プログラム
・NoticeTest.mq4(dllを呼び出すプログラム)
・LineNotification.cpp(dll化するプログラム)
・libLineNotification.dll
ここまでが前提となります。
発生している問題・エラーメッセージ
libcurlの関数を使ってDLL化を行い、mq4から呼び出そうとすると以下のエラーがエキスパートに出力されます。
2019.11.15 00:12:01.898 NoticeTest USDJPY,M5: not initialized 2019.11.15 00:12:01.897 Access violation read to 0x00409160
該当のソースコード
NoticeTest.mq4
MQL4
1#property copyright "meta" 2#property link "https://" 3#property version "1.00" 4 5#import "libLineNotification.dll" 6 int notifyLineAPI(); 7#import 8 9int OnInit() 10{ 11 int canRead = notifyLineAPI(); 12 Comment( canRead ); 13 14 return(INIT_SUCCEEDED); 15} 16 17int OnCalculate(const int rates_total, 18 const int prev_calculated, 19 const datetime &time[], 20 const double &open[], 21 const double &high[], 22 const double &low[], 23 const double &close[], 24 const long &tick_volume[], 25 const long &volume[], 26 const int &spread[]) 27{ 28 return (rates_total); 29}
LineNotification.cpp
c++
1#include <curl/curl.h> 2 3#define MT4_EXPFUNC __declspec(dllexport) 4 5extern "C" 6MT4_EXPFUNC int __stdcall notifyLineAPI() 7{ 8 CURLcode ret; 9 CURL *hnd; 10 curl_mime *mime1; 11 curl_mimepart *part1; 12 struct curl_slist *slist1; 13 14 mime1 = NULL; 15 slist1 = NULL; 16 slist1 = curl_slist_append(slist1, "Authorization: Bearer <ACCESS_TOKEN>"); 17 18 hnd = curl_easy_init(); 19 curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 102400L); 20 curl_easy_setopt(hnd, CURLOPT_URL, "https://notify-api.line.me/api/notify"); 21 curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, false); 22 curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L); 23 24 mime1 = curl_mime_init(hnd); 25 part1 = curl_mime_addpart(mime1); 26 27 curl_mime_data(part1, "ABC", CURL_ZERO_TERMINATED); 28 curl_mime_name(part1, "message"); 29 30 curl_easy_setopt(hnd, CURLOPT_MIMEPOST, mime1); 31 curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist1); 32 curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/7.67.0"); 33 curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); 34 curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_2TLS); 35 curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST"); 36 curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); 37 38 ret = curl_easy_perform(hnd); 39 40 curl_easy_cleanup(hnd); 41 hnd = NULL; 42 curl_mime_free(mime1); 43 mime1 = NULL; 44 curl_slist_free_all(slist1); 45 slist1 = NULL; 46 47 return (int)ret; 48}
c++のDLL化に使ったコマンド
PowerShell
1> mingw32-g++.exe LineNotification.cpp -l curl -o libLineNotification.dll "-Wl,-k,--output-def,DllLineNotification.def,--out-implib,libLineNotification.a"
試したこと
DLLのどこでエラーが発生しているのか確かめるために、LineNotifyAPIの中身を全てコメントアウトしreturn文だけ残し適当な数値を返させ、実行できるかどうか確かめました。これは、MT4で実行することができました。
一行ずつコメントアウトして確認したところ、最初に確認できた原因はslist1 = curl_slist_append(slist1, "Authorization: Bearer <ACCESS_TOKEN>");
この文で、Access Violationが起きているようでしたが、解決策がわかりませんでした。
補足情報(FW/ツールのバージョンなど)
libcurlに関しては、こちらのサイトにある誰かがビルド済みのものを使用しました。
https://curl.haxx.se/windows/
・curl for Windows 32bit
Specificaion欄の
・OpenSSL 1.1.1d [32bit]
・brotli 1.0.7 [32bit]
・libssh2 1.9.0 [32bit]
・nghttp2 1.39.2 [32bit]
・zlib 1.2.11 [32bit]
こちらをダウンロードしてMinGW直下に移動させました。
加えて
・Win32 OpenSSL v1.1.1d Light
をダウンロードしてProgram Files(x86)直下に保存しました。
ほかに必要な情報があればご指摘ください。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/11/15 17:33