创建您自己的MetaTrader扩展(dll)。 - 页 14

 

嗨,Mladen!

当我试图获得缓冲区[0]的值时,该值是类似于Buffer:2147483647

所以我认为这是不对的...应该有一个类似的值。1,23584

我做了一个测试,设置:缓冲区 = Rates[10].close。

有什么想法吗?

非常感谢,再见,AT

 
at120:
嗨,Mladen!

当我试图获得缓冲区[0]的值时,其值是类似于Buffer。2147483647

所以我认为这是不对的......应该有一个类似的值。1,23584

我做了一个测试,设置:缓冲区 = Rates[10].关闭。

有什么想法吗?

非常感谢,再见,AT

这个值就是所谓的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;-在mql中没有任何意义。你必须在buffer[]部分使用一些索引(比如buffer[0]=1;)。

 

嗨,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时遇到一个问题,该dll用于连接服务器,发送命令并关闭。我使用的是boost asio C++库,并从他们的网站上取了一个例子。我把代码作为控制台中的独立可执行文件进行了测试,它工作得很顺利,但当我把它转换成dll时,我看到了一个奇怪的字符串截断问题。

似乎只有字符串中的第一个字符被传递给了服务器。目前我正在发送一个测试字符串 "get time/n",但当收到消息时,只看到 "g"。

API看起来是这样的(完整的功能在下面)。

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

我读到MQL中的字符串实际上是一个结构,我尝试了建议的MqlStr结构,.......

结构MqlStr

{

int len;

char *string;

};

......,但这似乎也不起作用。它以一个无效的字符串挂起了服务器。

到目前为止,"最好 "的方法是我在下面列出的。

下面是我的测试Ea,它什么都不做,只是每一次 向服务器发送相同的字符串。

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

#属性版本 "1.00"

#property strict

#import "Boost.dll";

int messageOrder(string message, int length);

#import

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

//|专家初始化函数|

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

int OnInit()

{

//---

//---

return(INIT_SUCCEEDED);

}

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

//| 专家去初始化功能 | |

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

void OnDeinit(const int reason)

{

//---

}

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

//| 专家勾选功能 |

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

空白的OnTick()

{

//---

string message = "get time/n";

//打印("消息。", 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::resolver r(io_service)。

客户端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);

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 << "Exception:" << e.what() << "n";

}

返回0。

}

}

 
revivalfx:
我有一个问题,我创建了一个c++ dll,用来连接到服务器,发送命令并关闭。我正在使用boost asio C++库,并从他们的网站上取了一个例子。我把代码作为控制台中的独立可执行文件进行了测试,它工作得很顺利,但当我把它转换成dll时,我看到了一个奇怪的字符串截断问题。

似乎只有字符串中的第一个字符被传递给服务器。目前,我正在发送一个测试字符串 "get time/n",但在收到信息时只看到 "g"。

API看起来是这样的(完整的功能在下面)。

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

我读到MQL中的字符串实际上是一个结构,我尝试了建议的MqlStr结构,.......

结构MqlStr

{

int len;

char *string;

};

......,但这似乎也不起作用。它以一个无效的字符串挂起了服务器。

到目前为止,"最好 "的方法是我在下面列出的。

下面是我的测试Ea,它什么都不做,只是每一次向服务器发送相同的字符串。

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

#属性版本 "1.00"

#property strict

#import "Boost.dll";

int messageOrder(string message, int length);

#import

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

//|专家初始化函数|

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

int OnInit()

{

//---

//---

return(INIT_SUCCEEDED);

}

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

//| 专家去初始化功能 | |

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

void OnDeinit(const int reason)

{

//---

}

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

//| 专家勾选功能 |

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

空白的OnTick()

{

//---

string message = "get time/n";

//打印("消息。", 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::resolver r(io_service)。

客户端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);

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 << "Exception:" << e.what() << "n";

}

返回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,而不是基于先前帖子中的一个链接。

 

糟糕!我想我可以看看脚本下的例子。不考虑。谢谢......啊!Unicode。

 
revivalfx:
糟糕!我想我可以看看脚本下的例子。无视。谢谢......啊!Unicode。

这不是一条信息的长度吗?

 

你好,revalfx。

你应该使用wchar_t而不是char!我也有同样的问题!;-)

再见,AT