dllからMQL4へ参照渡しで複数のデータを返す方法を確認しましたが
文字列を返す方法を確認してみます
文字列を戻す
dllから複数の戻り値を取得する方法はこちらでやりました
文字列は多少面倒なので別にやってみることにしました
戻り値が文字列
最初は、戻り値をstringとして dll から文字列を取得する簡単な方法を試してみます
実装定義のワイド文字型の wchar_t を使うと便利です
また wchar_t は ‘L’ プレフィックスをつけます
1 2 3 4 5 6 7 8 |
// MQL4 string str = FShift07(); // dll wchar_t FShift07() { wchar_t* result = L"Hello world !"; return result; } |
まとめてみると、
MQL4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
... #import "Test_DLLstr.dll" string FShift07(); #import int count=0; int OnInit(){ return(INIT_SUCCEEDED); } void OnDeinit(const int reason){ } //●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● // OnTick() //●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● void OnTick(){ // only 1 task if(count==0){ string str = FShift07(); Print("str =" + str); count=1; } } |
Visual Studio 2022でdllを作成します
プロパティ設定が合っていないとこのコードの通りになりません(エラーになる)ので注意です
dllmain.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// dllmain.cpp : DLL アプリケーションのエントリ ポイントを定義します。 #include "pch.h" BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } __declspec(dllexport) wchar_t FShift07() { wchar_t* result = L"Hello world !"; return result; } |
これでストラテジーテスターで実行すると
Hello World! の文字列が戻ってきているのが分かります
returnで文字列を返すのは比較的簡単に済みます
参照渡しの文字列
複数の文字列を戻り値としたい場合は参照渡しとなります
但し、文字列配列はdllでは使えないので何個か別々に並べる程度になります
また長文はメモリの制限が無いか確認が必要です
戻す文字列の文字数は wcslen を使います
wcslenの引数はワイド文字列で、文字数はワイド (2 バイト) 文字の単位
それ以外はwcslen と strlen の動作は同じです
ワイド文字列のコピーには、wcscpy_s を使います
dllmain.cpp
1 2 3 4 5 6 7 8 9 10 11 |
... __declspec(dllexport) void FShift07(char* s1, char* s2) { wchar_t* res1 = L"Hello world!"; wchar_t* res2 = L"2nd Text"; int n1 = wcslen(res1); int n2 = wcslen(res2); wcscpy_s(s1, n1 + 1, res1); wcscpy_s(s2, n1 + 1, res2); } |
MQL4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
... #import "Test_DLLstr.dll" void FShift07(string &parst1, string &parst2); #import ... string str1 = ""; string str2 = ""; FShift07(str1, str2); Print("str1 =" + str1); Print("str2 =" + str2); ... |
ストラテジーテスターでは、
Hello World! と 2nd Text の文字列が戻ってきました
日本語の戻り値
文字列で漢字などを使用する想定であれば
setlocale も一緒に使ってみます
ロケールを使う場合、ヘッダーファイル locale.h をインクルードします
dllmain.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 |
... #include "locale.h" ... __declspec(dllexport) void FShift07(char* s1) { setlocale(LC_ALL, ""); wchar_t* res = L"外部関数の記述 別のモジュールで定義された外部関数は明示的に記述されるべきです。"; int n = wcslen(res); wcscpy_s(s1, n + 1, res); } |
MQL4
1 2 3 4 5 6 7 8 9 10 |
... #import "Test_DLLstr.dll" string FShift07(string &parst); #import ... string str = ""; FShift07(str); Print("str =" + str); ... |
ストラテジーテスターでは、日本語の文字列が返ってきています
2014年、MT4のbuild 509から600にアップデートされ、仕様が大幅に変わりました
MetaQuotes はMT4からMT5に移行したかったのでしょうけれど、MT4愛用者が
MT5に移行せずにとどまっているので、無理くりMT4をMT5に近づけていったのでは
と個人的におもいました
そのためでしょうか、MQL4もC言語のようなC++のような中途半端な感じです
関連記事: