2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MQL4 において mingw でコンパイルした DLL を使う

Posted at

表題の通りですが、インターネットを渉猟してもあまり成果がなかったので、備忘録として残しておきます。

背景

MQL4 から DLL による共有メモリを利用したい。(他プロセスと通信する時に便利なので。)
お金を出せば売っているが、参入障壁が低い技術に4000円も払いたくない。
一方、MS の VC++ のコミュニティ版は古いし、製品版はバカ高くて手が出ない。
そこで、手軽な mingw を使えないか、画策してみることにした。

コード

いきなりですが、作成した DLL のコードを載せておきます。

common.cc
#include <windows.h>

class SharedMemory {
 private:
  DWORD MemorySize = 1000 * 3 * sizeof(LONG);
  HANDLE handle = NULL;
  LPVOID lpPointer = NULL;

 public:
  SharedMemory(const char *name) {
    open(name);
  }

  ~SharedMemory() {
    close();
  }

  void write(int type, long tag, long value) {
    LONG *lpCell = (LONG *)lpPointer;
    lpCell[type * 3 + tag] = value;
  }

  long read(int type, long tag) {
    LONG *lpCell = (LONG *)lpPointer;
    return lpCell[type * 3 + tag];
  }

 private:
  void open(const char *name) {
    close();
    handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MemorySize, name);
    if (handle == NULL) {
      return;
    }
    lpPointer = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
    if (lpPointer == NULL) {
      CloseHandle(handle);
      return;
    }
    ZeroMemory(lpPointer, MemorySize);
  }

  void close() {
    if (lpPointer != NULL) {
      UnmapViewOfFile(lpPointer);
    }
    if (handle != NULL) {
      CloseHandle(handle);
    }
    }
  }
};

static SharedMemory mem("mql4_shared");

extern "C" __declspec(dllexport) void write_a(long tag, long value) {
        mem.write(0, tag, value);
}

extern "C" __declspec(dllexport) long read_a(long tag) {
        return mem.read(0, tag);
}

extern "C" __declspec(dllexport) void write_b(long tag, long value) {
        mem.write(1, tag, value);
}

extern "C" __declspec(dllexport) long read_b(long tag) {
        return mem.read(1, tag);
}

extern "C" __declspec(dllexport) void write_reg(long tag, long value) {
        mem.write(2, tag, value);
}

extern "C" __declspec(dllexport) long read_reg(long tag) {
        return mem.read(2, tag);
}

Windows の名前付き共有メモリを使っています。リソースの取得と解放が自動で行えるので、言語は C++ を使用しました。(エラートラップ全然入れていませんが、個人利用なので大目に見ることにします。)
ミソは export する関数を定義する際、__stdcall を入れないことです。

これを mingw g++ コンパイラでコンパイルして dll を作成し、

g++ -o common.dll -shared common.cc

MQL4 のデータフォルダの Terminal > (ハッシュ文字列) > MQL4 > Libraries の下にコピーします。
libstdc++-6.dll, libgcc_s_dw2-1.dll にも依存しているので一緒にコピーします。
(mingw インストールフォルダの、mingw/bin の下にあります。)

あとは MQL4 のスクリプトで、

#import "libgcc_s_dw2-1.dll"
#import "libstdc++-6.dll"
#import "common.dll"
  void write_a(int, int);
  int read_a(int);
  void write_b(int, int);
  int read_b(int);
  void write_reg(int, int);
  int read_reg(int);
#import

と定義すれば write_a(), ... 等の関数が利用できるようになります。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?