インポートした関数の呼び出し

MQL5 プログラムの実行時に関数をインポートするには、クライアント端末は事前結合を使用します。これは、プログラムがインポートされた関数を呼び出す場合は、対応するモジュール(EX5またはDLL)がプログラムロード中に読み込まれていることを意味します。MQL5 及び DLL ライブラリは呼び出しモジュールと同じスレッドで実行されます。

Drive:\Directory\FileName.Ext の様なモジュールの絶対パスの指定は推奨されていません。MQL5 ライブラリは terminal_dir\MQL5\Libraries フォルダから読み込まれます。ライブラリが見つからない場合、クライアント端末は terminal_dir\experts フォルダからの読み込みを試みます。

システムライブラリ(DLL)はオペレーティングシステムルールによって読み込みされます。ライブラリがすでに読み込みされている場合(例えば、別のエキスパートアドバイザーや更に別のクライアント端末が並列に実行されている)それは既に読み込まれたライブラリへのリクエストを使用します。それ以外の場合は、以下の順序で検索が実行されます。

  1. モジュールをインポートする dll が開始されたディレクトリ(モジュールとは、エキスパートアドバイザー、スクリプト、指標または EX5 ライブラリ)
  2. terminal_data_directory\MQL5\Libraries ディレクトリ(TERMINAL_DATA_PATH\MQL5\Libraries )
  3. MetaTrader 5 クライアント端末が開始されたディレクトリ
  4. システムディレクトリ
  5. ウィンドウディレクトリ
  6. 現在のディレクトリ
  7. PATH システム変数にリストされたディレクトリ

DLL ライブラリが他の DLL を使用する場合、使用される DLL が存在しない場合、初めの DLL は読み込むことが出来ません。

エキスパートアドバイザー(スクリプト、指標)が読み込まれる前に、全ての EX5 のライブラリモジュールの共通リストが形成されます。これは、読み込まれたエキスパートアドバイザー(スクリプト、指標)とライブラリー両方から使用されます。従って、EX5 ライブラリモジュールの複数使用のために1 回のみの読み込みが必要とされています。ライブラリはエキスパートアドバイザー(スクリプト、指標)の事前定義された変数を使用します。

インポートされたライブラリ EX5 は次の順序で検索されます。

  1. パスが EX5 をインポートしたエキスパートアドバイザー(スクリプト、指標)のディレクトリからの相対に設定されているディレクトリ
  2. terminal_directory\MQL5\Libraries ディレクトリ
  3. 全てのクライアント端末の共有ディレクトリ(Common\MQL5\Libraries)内の MQL5\Libraries ディレクトリ

DLL を MQL5 プログラムにインポートした関数は Windows API 呼び出しルールを守らなければなりません。そのような合意を確保するには、C または C ++ で記述されたプログラムのソーステキストで Microsoft(r) コンパイラに固有のキーワード __stdcall を使用します。この合意は以下のことを特徴としています。

  • 呼び出し側( MQ5 プログラム)は、スタックに正しくパラメータを組み合わせるために、(DLLからインポートされた)呼びだされる関数のプロトタイプを「見る」必要があります。
  • 呼び出し側( MQ5 プログラム)は、インポートされた関数が渡されたパラメータをこの順に読み込むように、右から左の逆の順序でスタックにパラメータを置きます 。
  • パラメータは、明示的に参照で渡されたもの(文字列)を除いて、値によって渡されます。
  • インポートされた関数は、渡されたパラメータを読み込むことにより、独立的にスタックをクリーンします。

インポートされた関数のプロトタイプを記述する場合、デフォルトのパラメータを使用することが出来ます。

対応するライブラリが読み込み出来ない場合、または DLL 使用が禁止されているかインポートされた関数が見つからない場合は、エキスパートアドバイザーは操作ログ(ログファイル)に「Expert Advisor stopped(エキスパートアドバイザー停止)」とのメッセージを書き入れて停止します。この場合、エキスパートアドバイザーは再初期化されるまで実行されません。エキスパートアドバイザーは、再コンパイルの結果として、またはそのプロパティの表が開かれ「OK」が押された後、再初期化することが出来ます。

パラメータの引き渡し

基本データ型のパラメータは全て明示的に参照で渡されるもの以外は値で受け渡されます。string の受け渡し時には、複製された文字列のバッファのアドレスが渡されます。文字列は参照で受け渡された場合、この文字列のバッファのアドレスが複製されずに DLL からインポートされた関数に渡されます。

動的配列、文字列、クラス、またその他の複雑な構造体を含む構造体や、列挙オブジェクトの静的または動的配列はパラメータとしてインポートされた関数に渡すことが出来ません。

配列を DLL に渡す場合 AS_SERIES フラグにかかわらず常にバッファの初めのアドレスが渡されます。DLL 内の関数は AS_SERIES フラグについては何も知らないので、渡された配列は不定のサイズ持つ静的配列となります。配列のサイズを指定するには追加のパラメータが使用されるべきです。