MetaTrader + C++: DLL

MetaTrader + C++: DLL

MetaTrader は、Windows DLL からエクスポートされた関数を呼び出すことができます。これは、Expert Advisor やインジケーターで、C または C++ のほうが保守しやすいコードが必要な場合、ネイティブライブラリへアクセスする必要がある場合、またはスクリプトだけの実装より高い性能が必要な場合に役立ちます。

重要な点はシンプルです。

  • DLL からプレーンな C スタイルの関数をエクスポートする。
  • MetaTrader が期待する正しい呼び出し規約を使う。
  • MQL のパラメーター型をネイティブ関数のシグネチャと一致させる。
  • スクリプト、インジケーター、または Expert Advisor を実行する前に、MetaTrader で DLL インポートを有効にする。

C++ DLL の例

最小限の C++ DLL では、次のように関数を公開できます。

// mt_example.cpp
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

extern "C" __declspec(dllexport) int __stdcall Add(int a, int b)
{
    return a + b;
}

extern "C" __declspec(dllexport) double __stdcall Multiply(double a, double b)
{
    return a * b;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
{
    return TRUE;
}

extern "C" は C++ の名前修飾を防ぐため、MetaTrader がエクスポートされた関数を名前で見つけられるようになります。__declspec(dllexport) は、その関数を DLL の外部から見えるようにします。__stdcall は、MQL からインポートされる関数で一般的に使われます。

DLL は MetaTrader ターミナルと同じアーキテクチャ向けにビルドしてください。32 ビットのターミナルには 32 ビット DLL が必要で、64 ビットのターミナルには 64 ビット DLL が必要です。

MQL インポートの例

DLL をコンパイルしたら、MetaTrader が読み込める場所に配置します。通常はターミナルの MQL4/Libraries または MQL5/Libraries ディレクトリです。

MQL4 の場合:

#import "mt_example.dll"
int Add(int a, int b);
double Multiply(double a, double b);
#import

void OnStart()
{
   int sum = Add(2, 3);
   double product = Multiply(1.5, 4.0);

   Print("sum = ", sum);
   Print("product = ", product);
}

MQL5 でも考え方は同じです。

#import "mt_example.dll"
int Add(int a, int b);
double Multiply(double a, double b);
#import

void OnStart()
{
   int sum = Add(2, 3);
   double product = Multiply(1.5, 4.0);

   Print("sum = ", sum);
   Print("product = ", product);
}

よくある確認項目

MetaTrader が DLL を呼び出せない場合は、まず次の項目を確認してください。

  1. ターミナル、およびスクリプト、インジケーター、または Expert Advisor の設定で DLL インポートが有効になっている。
  2. DLL が正しい Libraries ディレクトリに置かれている。
  3. DLL のアーキテクチャがターミナルのアーキテクチャと一致している。
  4. エクスポートされた関数名が修飾されていない。dumpbin /exports mt_example.dll や Dependency Walker のようなツールを使ってエクスポートを確認する。
  5. MQL の宣言が C++ 関数のシグネチャと完全に一致している。

文字列と配列に関する注意

intdouble のようなプリミティブ値は、渡すのが最も簡単です。文字列、配列、構造体は、メモリの所有権とレイアウトを MetaTrader が期待するものに合わせる必要があるため、より注意が必要です。

文字列を渡す場合は、まず小さなテスト関数を用意し、取引コードで使う前にエンコーディングとバッファサイズを確認してください。配列を渡す場合は、ポインターのようなパラメーターと長さの両方を渡し、DLL が指定されたサイズを超えて安全に読み取れるとは決して仮定しないでください。

実践的なルール

DLL インターフェイスは小さく安定させてください。取引ロジックや MetaTrader 固有の状態は MQL に任せ、C++ DLL には計算、別のネイティブライブラリとの連携、性能が重要な処理など、独立したネイティブ作業を担当させます。

Leave a Reply