MetaTrader拡張モジュール(DLL)の作成 - ページ 14

 

Mladenさん、こんにちは。

buffer[0]の値を取得しようとすると、Bufferのような値になっています。2147483647

ということで、これはおかしいと思うのですが・・・。というような値があるはずです。1,23584

をテストしてみました。

何かアイデアはありますか?

ありがとうございました、そしてさようなら、AT

 
at120:
こんにちは、Mladen!

buffer[0]の値を取得しようとすると、Bufferのような値になっています。2147483647

ということで、これはおかしいと思うのですが・・・。というような値があるはずです。1,23584

をテストしてみました。

何か思い当たることはありますか?

どうもありがとうございます。

この値はEMPTY_VALUEとして 知られているものです。

mql側で、バッファの宣言と値の割り当てに問題がないかをチェックしてください。また、C++側でバッファ(配列)の要素をどのように扱っているか確認してください。

 

こんにちは、Mladen!

DLLを呼び出したり、バッファを使ったりしてみたのですが、結果は芳しくありませんでした...。

C++のコードでバッファの値を1にしてみました、buffer[]=1; 変化なし...。

DLLを添付します(.zipから.dllにリネームしてください)、私は次のMQL4コードで呼び出します。

何かご意見/ヒントがありましたら、よろしくお願いします。

さようなら、AT

sma_rec.dll.zip

#property indicator_separate_window

#property indicator_buffers 1 // one indicator line to be plotted

#property indicator_color1 Red // plot colour is red - change via GUI

#import "sma_rec.dll"

void updateBuffer(MqlRates &rates[], double& buffer[], int bars, int indicator_counted, int period, double& internal_calcs[2] );

#import

extern int ma_period = 10; // default period is 10 - change via GUI

extern int ma_shift = 0; // default is no shift - change via GUI

double buffer[]; // the indicator buffer - the DLL will // write to this and it will be plotted

MqlRates Rates[];

double internal_calcs[2];

int init(){

// set up the indicator buffer

IndicatorBuffers(2);

SetIndexStyle(0, DRAW_LINE);

SetIndexShift(0, ma_shift);

SetIndexBuffer(0, buffer);

SetIndexLabel(0, "Recursive SMA");

IndicatorDigits(Digits);

return(0);

}

int start(){

ArrayCopyRates(Rates);

updateBuffer( Rates, buffer, Bars, IndicatorCounted(), ma_period, internal_calcs );

// Print("4 - close: ",Rates[0].close,"\n");

//Print("Buffer: ",buffer[0],"\n");

return(0);

}
ファイル:
 
at120:
こんにちは、Mladen!

DLLを呼び出したり、バッファを使ったりしてみたのですが、結果が出ません...。

C++のコードでバッファの値を1に設定しようとしました、buffer[]=1; 変化なし...

DLLを添付します(.zipから.dllにリネームしてください)、私は次のMQL4コードで呼び出します。

何かご意見/ヒントがありましたら、よろしくお願いします。

さようなら、AT

sma_rec.dll.zip

#property indicator_separate_window

#property indicator_buffers 1 // one indicator line to be plotted

#property indicator_color1 Red // plot colour is red - change via GUI

#import "sma_rec.dll"

void updateBuffer(MqlRates &rates[], double& buffer[], int bars, int indicator_counted, int period, double& internal_calcs[2] );

#import

extern int ma_period = 10; // default period is 10 - change via GUI

extern int ma_shift = 0; // default is no shift - change via GUI

double buffer[]; // the indicator buffer - the DLL will // write to this and it will be plotted

MqlRates Rates[];

double internal_calcs[2];

int init(){

// set up the indicator buffer

IndicatorBuffers(2);

SetIndexStyle(0, DRAW_LINE);

SetIndexShift(0, ma_shift);

SetIndexBuffer(0, buffer);

SetIndexLabel(0, "Recursive SMA");

IndicatorDigits(Digits);

return(0);

}

int start(){

ArrayCopyRates(Rates);

updateBuffer( Rates, buffer, Bars, IndicatorCounted(), ma_period, internal_calcs );

// Print("4 - close: ",Rates[0].close,"\n");

//Print("Buffer: ",buffer[0],"\n");

return(0);

}

buffer[]=1;を使うことはできません。buffer[]の部分に何らかのインデックスを使用する必要があります。

 

Mladenさん、こんにちは。

私はC++で以下のようにしました。

buffer = 1;

ということで、これで普通に動くはずなのですが・・・。

C++のコードは以下のような感じです。

ありがとうございました。

さようなら、AT

#include

#include "stdafx.h"

#include

#define WIN32_LEAN_AND_MEAN

#define MT4_EXPFUNC __declspec(dllexport)

//+------------------------------------------------------------------+

//| MT4 HISTORY DATA STRUCT |

//+------------------------------------------------------------------+

#pragma pack(push,1)

struct RateInfo

{

__int64 ctm;

double open;

double low;

double high;

double close;

unsigned __int64 vol_tick;

int spread;

unsigned __int64 vol_real;

};

#pragma pack(pop)

struct MqlStr

{

int len;

char *string;

};

MT4_EXPFUNC void __stdcall updateBuffer(const RateInfo* Rates, double buffer[],int Bars, int IndicatorCounted, int ma_period, double internal_calcs[2] )

{

//---

if(Rates==NULL)

{

printf("updateBuffer: NULL array\n");

}

//---

if(Rates != NULL)

{

printf("updateBuffer: something is in array\n");

}

//---

if(buffer==NULL)

{

printf("updateBuffer: NULL array\n");

}

//---

if(Bars<0)

{

printf("updateBuffer: wrong Bars number (%d)\n", Bars);

}

//---

if(ma_period<0)

{

printf("updateBuffer: wrong MA Period (%d)\n", ma_period);

}

//---

if(ma_period==10)

{

printf("updateBuffer: 10 MA Period (%d)\n", ma_period);

}

// buffer = 1;

//buffer = ( buffer - internal_calcs[0] ) + ( Rates.close/ma_period ); // calculate new SMA value//

// check if the DLL is being called for the very first time

if ( IndicatorCounted == 0 )

{

buffer[0] = Rates[0].close;

buffer[1] = ( Rates[0].close + Rates[1].close ) / 2.0;

for( int ii = 2 ; ii < ma_period ; ii++ )

{

buffer = ( ( buffer * ii ) / (ii+1) ) + ( Rates.close/(ii+1) );

}

for( int ii = ma_period ; ii < Bars - 1 ; ii++ )

{

buffer = ( buffer - (Rates.close/ma_period) ) + ( Rates.close/ma_period );

}

internal_calcs[0] = (Rates.close/ma_period);

internal_calcs[1] = Bars - 1; // how many indicator values calculated so far

}

if ( IndicatorCounted > 0 && (Bars - 1) > internal_calcs[1] ) // evaluates to TRUE if there is a new bar

{

buffer = ( buffer - internal_calcs[0] ) + ( Rates.close/ma_period ); // calculate new SMA value

internal_calcs[0] = (Rates.close/ma_period); // update // internal_calcs with new value for next SMA calc.

internal_calcs[1] = Bars - 1; // update how many indicator values calculated so far

} // end of ( IndicatorCounted > 0 && (Bars - 1) > internal_calcs[1]) if // statement

} // end of main function call

 

サーバーに接続し、コマンドを送信して終了するために作成したc++ dllで問題が発生しています。私はboost asio C++ライブラリを使用し、そのウェブサイトからサンプルを取得しました。このコードをコンソールでスタンドアローン実行ファイルとしてテストしたところ、見事に動作しましたが、DLLに変換したところ、そこで奇妙な文字列の切り捨ての問題が発生しました。

文字列の最初の文字だけがサーバーに渡されるようです。現在、私はテスト文字列 "get timeanthus "を送信していますが、メッセージを受信したとき、"g "しか見えません。

APIは以下のようなものです(完全な関数は以下にあります)。

MT4_EXPFUNC int __stdcall messageOrder(char* message, int length)

MQLの文字列は実際には構造体であると読んだことがあり、提案されたMqlStr構造体を試してみました、、、、、。

構造体MqlStr

{

int len;

char *string;

};

......しかし、これもうまくいかないようです。無効な文字列でサーバーがハングアップしてしまうのです。

今までのところ、一番うまくいったのは、以下に挙げたものです。

以下は、同じ文字列をサーバーに送信する以外何もしない私のテストeaです。

---------------

#property バージョン "1.00"

#property strict

#import "Boost.dll";

int messageOrder(string message, int length);

#import

//+------------------------------------------------------------------+

//| エキスパート初期化関数

//+------------------------------------------------------------------+

int OnInit()

{

//---

//---

return(INIT_SUCCEEDED);

}

//+------------------------------------------------------------------+

//| 専門家による初期化関数

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

{

//---

}

//+------------------------------------------------------------------+

//| エキスパートティック関数

//+------------------------------------------------------------------+

void OnTick()

{

//---

string message = "get timexxn";

//Print("message:", message, " length = ", StringLen(message)); //Print("message:", message, " length = ", StringLen(message));

messageOrder(message, StringLen(message))。

}

//+------------------------------------------------------------------+

dllのエクスポートは以下の通りです。メッセージを受信した後にstd::stringを作成し、その文字列をサーバーに送信しています。目下の問題は、MQL文字列からC++ char *への変換です。

明らかに何か間違ったことをしています。どなたか助けていただけませんか?

extern "C"

{

#define MT4_EXPFUNC __declspec(dllexport)

MT4_EXPFUNC int __stdcall messageOrder(char* message, int length)

{

トライ

{

boost::asio::io_service io_service;

tcp::リゾルバr(io_service);

クライアントc(io_service);

//char * p;

//char msg[1024];

//int i;

//for(i = 0, p= メッセージ; i < 長さ; i++, p++)

//{

// msg = *p;

//}

//std::string line = std::string(msg);

std::string line = message;

c.assignMessage(line);

c.start(r.resolve(tcp::resolver::query("127.0.0.1", "100")));

io_service.run()。

}

catch (std::exception& e)

{

std::cerr << "例外が発生しました。" << e.what() << "\n";

}

return 0;

}

}

 
revivalfx:
私はサーバーに接続し、コマンドを送信して終了するために作成したC + + DLLで問題を抱えています。私はboost asio C++ライブラリを使用しており、彼らのウェブサイトから例を取りました。このコードをコンソールで単独実行ファイルとしてテストしたところ、見事に動作しましたが、DLLに変換すると、そこで奇妙な文字列の切り詰めの問題が発生しました。

文字列の最初の文字だけがサーバーに渡されるようです。現在、私はテスト文字列 "get timeanthus "を送信していますが、メッセージを受信したとき、"g "しか見えません。

APIは以下のようなものです(完全な関数は以下にあります)。

MT4_EXPFUNC int __stdcall messageOrder(char* message, int length)

MQLの文字列は実際には構造体であると読んだことがあり、提案されたMqlStr構造体を試してみました、、、、、。

構造体MqlStr

{

int len;

char *string;

};

......しかし、これもうまくいかないようです。無効な文字列でサーバーがハングアップしてしまうのです。

今までのところ、一番うまくいったのは、以下に挙げたものです。

以下は、同じ文字列をサーバーに送信する以外何もしない私のテストeaです。

---------------

#property バージョン "1.00"

#property strict

#import "Boost.dll";

int messageOrder(string message, int length);

#import

//+------------------------------------------------------------------+

//| エキスパート初期化関数

//+------------------------------------------------------------------+

int OnInit()

{

//---

//---

return(INIT_SUCCEEDED);

}

//+------------------------------------------------------------------+

//| 専門家による初期化関数

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

{

//---

}

//+------------------------------------------------------------------+

//| エキスパートティック関数

//+------------------------------------------------------------------+

void OnTick()

{

//---

string message = "get timexxn";

//Print("message:", message, " length = ", StringLen(message)); //Print("message:", message, " length = ", StringLen(message));

messageOrder(message, StringLen(message))。

}

//+------------------------------------------------------------------+

dllのエクスポートは以下の通りです。メッセージを受信した後にstd::stringを作成し、その文字列をサーバーに送信しています。目下の問題は、MQL文字列からC++ char *への変換です。

明らかに何か間違ったことをしています。どなたか助けていただけませんか?

extern "C"

{

#define MT4_EXPFUNC __declspec(dllexport)

MT4_EXPFUNC int __stdcall messageOrder(char* message, int length)

{

トライ

{

boost::asio::io_service io_service;

tcp::リゾルバr(io_service);

クライアントc(io_service);

//char * p;

//char msg[1024];

//int i;

//for(i = 0, p= メッセージ; i < 長さ; i++, p++)

//{

// msg = *p;

//}

//std::string line = std::string(msg);

std::string line = message;

c.assignMessage(line);

c.start(r.resolve(tcp::resolver::query("127.0.0.1", "100")));

io_service.run()。

}

catch (std::exception& e)

{

std::cerr << "例外が発生しました。" << e.what() << "\n";

}

return 0;

}

}

MqlStr構造体を使うときに、不適切な解凍をしていたことが判明しました。

今私はしています。

struct MqlStr

{

int len;

char *string;

};

extern "C"

{

#define MT4_EXPFUNC __declspec(dllexport)

MT4_EXPFUNC int __stdcall messageOrder(MqlStr * message, int length)

/// MT4_EXPFUNC int __stdcall messageOrder(char* message, int length)

{

std::string line;

try

{

boost::asio::io_service io_service;

tcp::resolver r(io_service);

client c(io_service);

//char * p;

//char msg[1024];

//int i;

//for(i = 0, p= message; i < length; i++, p++)

//{

// msg = *p;

//}

//std::string line = std::string(msg);

line = message[0].string;

c.assignMessage(line);

c.start(r.resolve(tcp::resolver::query("127.0.0.1", "100")));

io_service.run();

}

catch (std::exception& e)

{

std::cerr << "Exception: " << e.what() << "\n";

}

//return line.length();

return strlen(message[0].string);

//return message[0].len;

}

}

[/CODE]

I return the length of the MqlStr string and it is always 1. So it is doing exactly the same as the implementation above.

Here's the MQL code.

[CODE]

#property version "1.00"

#property strict

#import "Boost.dll";

int messageOrder(string message, int length);

#import

//+------------------------------------------------------------------+

//| Expert initialization function |

//+------------------------------------------------------------------+

int OnInit()

{

//---

//---

return(INIT_SUCCEEDED);

}

//+------------------------------------------------------------------+

//| Expert deinitialization function |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

{

//---

}

//+------------------------------------------------------------------+

//| Expert tick function |

//+------------------------------------------------------------------+

void OnTick()

{

//--- int len = 0;

string message = "get time\n";

//Print("message: ", message, " length = ", StringLen(message));

len = messageOrder(message, StringLen(message)); Print("len ", len);

}

//+------------------------------------------------------------------+

私は今、以前の投稿のリンクに基づいて、代わりにC#のDLLを調査しています。

 

畜生!scriptsの下にあるサンプルを見ればよかったんですね。ありがとうございます......。あ!ユニコードだ。

 
revivalfx:
というわけで。scriptsの下にあるサンプルを見ればよかったかな。 無視。ありがとうございます......。あ!ユニコードだ。

メッセージの長さじゃなかった?

 

revalfxさん、こんにちは。

charの代わりにwchar_tを使いたいのですね!私もそうでした。)

では、ATさん。