記事"f()10分でできるMQL5 のためのDLL (パート II): Visual Studio 2017で作成"についてのディスカッション

 

新しい記事 f()10分でできるMQL5 のためのDLL (パート II): Visual Studio 2017で作成 はパブリッシュされました:

元の基本となる記事との関連性は失われていませんが、このトピックに興味がある場合は、まず最初の記事を読んでください。 しかし、前回の記事から時間が経過しているので、現在の Visual Studio 2017 には、更新されたインターフェイスがあります。 また、MetaTrader5プラットフォームにも新しい機能が追加されました。 この記事では、DLLのプロジェクト開発、およびセットアップと MetaTrader5 ツールとのやり取りについて説明します。

シンプルなDLL の作成

全体のプロセスは、すでに元の記事で説明されていました. ここでは、ソフトウェアの更新と変更を考慮して繰り返します。

Visual Studio 2017 を開き、[ファイル]-> [新規] → [プロジェクト] に移動します。 新しいプロジェクトウィンドウの左の部分で、Visual C++ の一覧を展開し、そこから Windows デスクトップを選択します。 中央部の Windows デスクトップウィザードの行を選択します。 下の部分のインプットフィールドを使用して、プロジェクト名を編集することができます (意味がわかる名前を設定することをお勧めします) 。それから、プロジェクトの場所を設定します (提案どおりのままにすることをお勧めします)。 [OK] をクリックし、次のウィンドウに進みます。


ドロップダウンリストからダイナミックリンクライブラリ (DLL) を選択し、「エクスポートシンボル 」をチェックします。 この項目の確認はオプションですが、初心者の方にお勧めです。 この場合、プロジェクトファイルにデモコードが追加されます。 このコードは、表示してから削除またはコメントすることができます。 "OK " をクリックすると、プロジェクトファイルが作成され、編集できるようになります。 ただし、最初にプロジェクトの設定を考慮する必要があります。 まず、MetaTrader5 は64ビットライブラリでしか動作しないことを覚えておいてください。 32ビットのDLL を接続しようとすると、次のメッセージが表示されます。

'E:\...\MQL5\Libraries\Project2.dll' is not 64-bit version
Cannot load 'E:\MetaTrader5\MQL5\Libraries\Project2DLL' [193]

したがって、このライブラリを使用することはできません。

作者: Andrei Novichkov

 

もしかしたら誰かの役に立つかもしれない、最近僕はこの方法でやっている:

CodeLightのIDEを使うことは可能だ。Studioと比べると、速くて「貪欲」ではないし、Microsoftを含むさまざまなコンパイラを受け入れる。

変な話ですが、gccを使ったDLLの方が簡単にビルドできます。DLLプロジェクトの 設定で、必要なタルチェーン(MT4ならgcc32ビット、MT5ならgcc64)を指定する。以上です。オプションでPostBuildに「DLLをMT階層にコピーする」コマンドを追加する。

.defをいじる必要はなく、必要に応じてdefが自動生成される。 ちなみに、DllMainは全く不要なので、捨ててしまって構わない:-)正確には、DllMainが必要な場合もあるが、ごくまれで、MTライブラリの必要性を超えている。

 

もうひとつのポイントは、記事には書かれていないが、求められていることだ。

もしC++なら、おそらくクラスがあるはずで、MqlとC++の両方にあるはずだ。

「C++のクラスをMqlにドラッグする」。

1. クラスを書く(または既成のものを使う) :-)

こんな感じ:

#ifndef  MQLPLUG_H
#define  MQLPLUG_H 1
#include "mql45.h"
/** MTに「ドラッグ」されるクラスの例
**/
class Plug {
public:
        Plug();
        ~Plug();

        mql_int OnInit();
        void OnDeinit(mql_int);

        mql_int Sum(mql_int,mql_int);
        mql_double Median(MqlRates *rate);
};
/* C++のメソッドはDLLを通して "ドラッグ "できないが、Cの関数だけは
 、呼び出しをオブジェクト
*/に委譲する単純な関数が作られる。
MQL_API(Plug *) Plug_New();
MQL_API(void) Plug_Delete(Plug *);
MQL_API(mql_int) Plug_OnInit(Plug *);
MQL_API(void) Plug_OnDeinit(Plug *,mql_int);
MQL_API(mql_int) Plug_Sum(Plug *,mql_int,mql_int);
MQL_API(mql_double) Plug_Median(Plug *,MqlRates *rate);
#endif

2.最初の引数はオブジェクトへのポインターで、関数内部でその正しさをチェックし、メソッドを呼び出し、例外をキャッチする。

/// MqlPlug.cpp
#include "MqlPlug.h"
/*** プラグ・クラスのメソッドのラッパー関数
 (_Newを除く)はすべて、
 オブジェクトへのポインタを第一引数として受け取ります。 その他の引数は、
 メソッドと同じです。渡されたポインタが正しい(nullptrではない)場合、メソッド
 が呼び出され、同時にすべての例外
***/ が捕捉されます。
/// コンストラクタ
MQL_API(Plug *)
Plug_New() {
        try {
                return new Plug;
        } catch (...) {
        }
        return nullptr;
}
/// デストラクタ
MQL_API(void)
Plug_Delete(Plug *plug) {
        try {
                delete plug;
        } catch (...) {
        }
}
// その他の方法
MQL_API(mql_int)
Plug_Sum(Plug *plug,mql_int one,mql_int two) {
        try {
                if (plug) return plug->Sum(one,two);
        } catch (...) {
        }
        return 0;
}
// и так далее

3. そして最後にMql !import ディレクティブにfunction-delegatesを記述し、objというフィールドと、オブジェクトへのハンドラ(ポインタ)と、デリゲートを呼び出すメソッドを持つクラスを記述する。

#ifdef __MQL4__
// 4kの場合、ディスクリプタ(ポインタ)は32ビット)
#define  HANDLE int
#else
// 5 - 64の場合
#define  HANDLE long
#endif

#import "Mql4Plug.dll"
HANDLE Plug_New(void);
void Plug_Delete(HANDLE);
int Plug_OnInit(HANDLE);
void Plug_OnDeinit(HANDLE,const int reason);
int Plug_Sum(HANDLE,int,int);
double Plug_Median(HANDLE,MqlRates &);
#import

class Plug {
public:
   HANDLE obj;
   Plug() {
      obj = Plug_New();
   }
   ~Plug() {
      Plug_Delete(obj);
   }
   int OnInit() {
      if (obj != NULL) {
         return Plug_OnInit(obj);
      }
      return INIT_FAILED;
   }
   void OnDeinit(const int reason) {
      if (obj != NULL) {
         Plug_OnDeinit(obj,reason);
      }
   }
   int Sum(int one,int two) {
      if (obj != NULL) {
         return Plug_Sum(obj,one,two);
      }
      return 0;
   }
   double Median(MqlRates &rates) {
      if (obj!=NULL) {
         return Plug_Median(obj,rates);
      }
      return EMPTY_VALUE;
   }
};

追記/一度そのような要求があり、私は正直に説明しようとした。しかし、私があまり良い先生ではなかったのか、それとも私のプログラミングに対する見方があまり良くなかったのか :-)) 。しかし、人気のある例は残った。

 

こんばんは。すぐにすべてに答えるようにします。

Maxim Kuznetsov:
...

.defをいじる必要はありません。必要であればdefは自動的に生成されます。 ちなみにDllMainは全く不要なので、捨ててしまってかまいません:-)正確には、DllMainが必要になることもあるが、ごく稀であり、MTライブラリの必要性を超えている。

この記事は、定義ファイルをどのように生成するか、それができるかどうか、そのためにどのツールを使うかについて書いているのではない。この記事では、定義ファイルが何のために必要なのか、VSで何に使えるのか、定義ファイルから何が生まれるのかについて述べている。そして、それをどのように作るのか、何をいつ使うのか、それは問題ではない。

DllMainについて。理論的には正しい。そう、この関数はなくてもできる。私は、DllMainがあっても呼び出されないツールを知っている。しかし、「境界を越えている」というあなたの断定的な結論にはまったく同意できない。私は、そのような結論は開発者自身が下すべきだと確信している。もしそれが必要なら、DllMainで何かを呼び出せばいい。そうしたくなければ、別にエクスポート可能な関数を 書けばいい。個人的には、この追加機能を簡単に奪ってしまうほどの能力はないと思っている。

Maxim Kuznetsov:

もう1点、記事には書かれていないが、要望がある。

もしC++なら、おそらくMqlとC++の両方にクラスがあるはずだ。

「C++のクラスをMqlにドラッグする」。

クラスのエクスポートがある必要はない。))この機能について言及してくれてありがとう。個人的には、このようなことをすることは思いつかなかったし、初心者の開発者にこのようなテクニックを勧めることもなかった。このコードの人為性と非合理性を見てほしい。そして、開発者にこのような奇妙な方法でポインターを扱わせる必然性があるのだろうか。言い換えれば、このコードがクラッシュしないのであれば、理論的な例としては面白いが、実用的な観点からは - ほとんどない)。 さらに言うと、私の意見では、開発者がこのようなエクスポートを必要とする場合、その設計を間違えている可能性が高い。 その上、記事の約半分が構造体に割かれており、これらは「ほとんどクラス」であるという事実に注目してもらいたい。C++17のすべてを喜んでMQLに押し込もうとするフォーラムの仲間の足跡を追わないためにも、ここで立ち止まる価値はある。)

 

議論しているわけではない。)

ただ、思いついたことを書いてみただけだ。

この記事に反論するつもりはないが

二つの言語の接点にどんな「初心者プログラマー」がいるのでしょうか?

PS/ ところで、あなたは長い記憶力を持っていますね :-)

 
Maxim Kuznetsov:

反論しているわけではないよ。)

誰かの役に立つかもしれない。

ありがとう。

しかし、残念ながら、そのような良い例はフォーラムのトピックにあることが非常に多く、それを見つけるのは非常に困難です。)

もしあなたが怠け者でないなら、そのような優れた例をあなたのブログに載せるべきです、少なくとも、より早く見つけられる可能性があります。ちなみに、このフォーラムはgoogleに非常によくインデックスされており、ニューラルネットワークのトピックに関するクエリはほとんどすべてMQLの記事にたどり着きます ;)

 
Maxim Kuznetsov:

反論しているわけではないよ。)

誰かの役に立つかもしれない。

記事に反論することなく

二つの言語の接点にどんな「初心者プログラマー」がいるのか?

追記/ところで、メモリが多いですね。

メモリってなんだ、どこかで間違えたか?

初心者プログラマーというのは拡大解釈で、私はPythonの初心者です。他にも初心者と呼べるものはたくさんある。ここでも、ライブラリを作ったことがない人が、20年間CADをやっていたり、Adobeプログラムのプラグインを書いていたりしたら、どういう状況になるでしょうか?もちろん、彼は新しい分野では初心者だが、古い分野では経験豊富だ。とにかく、ここではこの用語はそれほど重要ではない。

 
C++のDLLでメタトレーダー内にカスタムメニューを作成できますか?
 
いいえ)
 
記事をありがとう。VS2022には、変更点のバックログを使った続編が予定されているのでしょうか?
 
今のところ予定はない