MQL4プログラムがインポート関数を使用する場合、クライアントターミナルは事前バインディングします。
インポート関数の呼び出しを行うプログラムは、プログラムにロードされる時に対応モジュール(.ex4または.dll)がロードされます。
MQL4とDLLライブラリは呼び出し元モジュールのスレッドで実行されます。
絶対パスでモジュールを指定(カレントドライブ:\ディレクトリ\モジュール名)して使用する事はお勧め出来ません。
MQL4ライブラリは"ターミナルディレクトリ\MQL4\Libraries"フォルダからロードされます。
ライブラリが見つからなかった場合、クライアントターミナルは"ターミナルディレクトリ\experts"フォルダを検索します。
システムライブラリ(dll)はオペレーティングシステムのルールでロードされます。
ライブラリが既にロードされている場合(例えば、別のEAや他クライアントターミナルが並行して実行している)、
既にロードされたライブラリが使用されます。
それ以外の場合は、以下順序で検索されます。
■検索順
- dllをインポートしたモジュール(EA,スクリプト,インジケータ,ex4ライブラリ)のディレクトリ。
- "ターミナルデータディレクトリ\MQL4\Libraries"(TERMINAL_DATA_PATH\MQL4\Libraries)ディレクトリ。
- MT4クライアントターミナルを起動したディレクトリ
- システムディレクトリ
- ウィンドウズディレクトリ
- 現在のディレクトリ
- PATHシステム変数にリストされているディレクトリ
DLLライブラリ使用中に別のDLLを使用する場合、二番目のDLLが存在しない時は一番目のDLLをロードできません。
MQLプログラム(EA、スクリプト、インジケータ)がロードされる前に、全てのex4ライブラリモジュールの共通リストが形成されます。
これはロードされたMQLプログラムとライブラリの両方から使用されます。
したがってex4ライブラリモジュールを複数使用する為に1回だけロードを必要とします。
ライブラリはMQL4プログラムの
定義済み変数を使用します。
インポートライブラリex4は次の順序で検索します
- ex4をインポートしたMQLプログラムのディレクトリからの相対設定ディレクトリから検索します。
- \ターミナルディレクトリ\MQL4\Librariesのディレクトリから検索します。
- 全てのMT4クライアントターミナルの共通ディレクトリ内の\MQL4\Librariesのディレクトリから検索します。
MQL4プログラムへDLL
インポートした関数は、WindowsAPIの呼び出しルールを守らなければなりません。
このような合意を確保する為には、CまたはC++言語が書かれたプログラムのソースコードで、Microsoft(R)コンパイラに固有キーワード(__stdcall)を使用します。
この合意は以下特徴があります。
- 呼び出し側(MQL4プログラム)は、スタックに引数を正しくバインドする為に、呼ばれる関数(DLLからインポートされた関数)のプロトタイプを見る必要があります。
- 呼び出し側(MQL4プログラム)が右から左に逆の順序でスタックへ引数を置き、インポートされた関数は渡された引数をこの順に読み込みます。
- 引数が明示的に参照渡し(文字列の場合)にしたもの以外は、値で渡されます。
- インポートされた関数は、渡されたパラメータを読み込む事により、独立してスタックをクリーンアップします。
インポートされた関数のプロトタイプを記述する場合、デフォルトのパラメータを使用する事が出来ます。
対応するライブラリがロード出来ない場合、またはDLL使用が禁止されている場合、またはインポートされた関数が見つからない場合は、
EA(MQL4プログラム)はジャーナル(ログファイル)に"Expert Advisor stopped"とメッセージを出力し動作を停止します。
この場合、MQL4プログラムは再初期化されるまで実行されません。
MQL4プログラムは再コンパイルするか、プロパティテーブルで「OK」を押した後に再初期化する事が出来ます。
引数渡し
シンプルな型の引数は明示的に参照渡しにしたもの以外は、全て値で渡されます。
stringが渡されると、コピーされた文字列バッファのアドレスが渡されます。
文字列が参照によって渡された場合、この文字列バッファアドレスはコピーせずDLLからインポート関数に渡されます。
構造体(
動的配列、文字列、クラス、複雑な構造体を含む)は引数としてインポート関数に渡す事は出来ません。
DLLに配列を渡す時、データバッファの先頭アドレス(
AS_SERIESフラグに関係なく)が常に渡されます。
DLL内の関数はAS_SERIESフラグについては何も知らない為、渡された配列は長さ不明の静的配列です。
配列のサイズを指定する為の引数を追加するべきです。