参照渡しとライブラリにまつわるバグ?
公式フォーラムで、参照渡しとライブラリにまつわるバグ?について投稿があったので紹介しておきます。
参照渡しを知らない人は、「参照渡しは、とても便利かも!」を読んで頂くとして、以下に簡単な再現コードを書きました。
まずは、ライブラリを使わない場合のコード
void foo1(int &ret) // & を付けて、retを参照渡し宣言 { ret = 123; // retへの値の代入は、実際は、num に値を代入することになる。 } ///////////////////////////////////////////////// int start() { int num = 0; foo1(num); Alert(num); // num=123 が表示される。 }
特に問題のない、ごく普通な参照渡しのサンプルコードです。
関数 foo1 を 外部ファイル test.mq4 ( test.ex4 ) としてライブラリ化してみると…
// \experts\libraries\test.mq4 #property library // ライブラリ化時に忘れてはいけない一行 void foo1(int &ret) { ret=123; }
呼び出し側は、以下の通り。
#import "test.ex4" void foo1(int &ret); #import ///////////////////////////////////////////////// int start() { int num = 0; foo1(num); // 参照渡しで123が代入されることを期待するも… Alert(num); // num=0 が表示される。(ノ_<。) }
ライブラリ化の手順には、一見なんの誤りも無いように見えますが、結果として意図した動作をしなくなります。
そこで、オンラインヘルプを確認すると、
If there is a need to pass data of the int or double type, then the one-dimensional array of the corresponding type should be passed by reference as a parameter.
と書かれているので、上記の場合、MT4 のバグではなく仕様ということで、配列の参照渡しに書き換える必要があるのでした。参照渡しを多用したコードをライブラリ化する時は要注意ですね。
(個人的には、あまりex4のライブラリ化はしないで、#include だけで済ませるほうが良いと思います...)
いやぁ、プログラムって本っ当に難しいもんですね〜 by Mike Mizno