자신만의 MetaTrader 확장 프로그램(dll) 생성 - 페이지 14

 

안녕 믈라덴!

buffer[0] 값을 얻으려고 할 때 값은 Buffer: 2147483647과 같습니다.

그래서 나는 이것이 옳지 않다고 생각합니다... 다음과 같은 값이 있어야 합니다: 1,23584

내가 테스트하고 설정했을 때: buffer = Rates[10].close;

어떤 아이디어?

감사합니다. AT

 
at120:
안녕 믈라덴!

buffer[0] 값을 얻으려고 할 때 값은 Buffer: 2147483647과 같습니다.

그래서 나는 이것이 옳지 않다고 생각합니다... 다음과 같은 값이 있어야 합니다: 1,23584

내가 테스트하고 설정했을 때: buffer = Rates[10].close;

어떤 아이디어?

감사합니다. AT

그 값은 EMPTY_VALUE 로 알려진 값입니다.

mql 측에서 버퍼 선언과 값 할당이 모두 괜찮은지 확인하십시오. 또한 C++ 측에서 버퍼(배열) 요소를 어떻게 처리하고 있는지 확인하십시오.

 

안녕 믈라덴!

DLL을 호출하고 버퍼를 사용하여 무언가를 시도했지만 긍정적 인 결과가 없었습니다 ...

C++ 코드의 버퍼 값을 1로 설정하려고 했습니다. buffer[]=1; 변경 없음...

다음 MQL4 코드로 호출하는 DLL을 첨부했습니다(.zip do .dll에서 이름을 바꾸십시오).

모든 입력/힌트에 감사드립니다...

안녕, 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:
안녕 믈라덴!

DLL을 호출하고 버퍼를 사용하여 무언가를 시도했지만 긍정적 인 결과가 없었습니다 ...

C++ 코드의 버퍼 값을 1로 설정하려고 했습니다. buffer[]=1; 변경 없음...

다음 MQL4 코드로 호출하는 DLL을 첨부했습니다(.zip do .dll에서 이름을 바꾸십시오).

모든 입력/힌트에 감사드립니다...

안녕, 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);

}

버퍼[]=1을 사용할 수 없습니다. - 그것은 mql에서 아무 의미가 없습니다. buffer[] 부분에서 일부 인덱스를 사용해야 합니다(예: buffer[0]=1; )

 

안녕 믈라덴!

C++에서 다음을 사용했습니다.

버퍼 = 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 time\n"을 보내고 있지만 메시지가 수신되면 "g"만 표시됩니다.

API는 다음과 같습니다(전체 기능은 아래에 있음).

MT4_EXPFUNC int __stdcall messageOrder(문자* 메시지, 정수 길이)

MQL의 문자열이 실제로 구조라는 것을 읽었고 제안된 MqlStr 구조를 시도했습니다........

구조체 MqlStr

{

int 렌;

문자 *문자열;

};

......하지만 그것도 안되는 것 같습니다. 유효하지 않은 문자열로 서버를 정지시킵니다.

지금까지 "최고"로 작동한 것은 아래에 나열한 것입니다.

다음은 매 틱마다 동일한 문자열을 서버에 보내는 것 외에는 아무것도 하지 않는 테스트 ea입니다.

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

#속성 버전 "1.00"

#속성엄격

#import "Boost.dll";

int messageOrder(문자열 메시지, int 길이);

#수입

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

//| 전문가 초기화 기능 |

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

int OnInit()

{

//---

//---

반환(INIT_SUCCEEDED);

}

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

//| 전문적인 초기화 해제 기능 |

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

무효 OnDeinit(const int 이유)

{

//---

}

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

//| 전문가 틱 기능 |

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

무효 OnTick()

{

//---

문자열 메시지 = "시간 가져오기\n";

//Print("메시지: ", 메시지, " 길이 = ", StringLen(메시지));

messageOrder(메시지, StringLen(메시지));

}

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

dll 내보내기는 아래와 같습니다. 메시지가 수신된 후 std::string을 생성한 다음 해당 문자열을 서버로 보냅니다. 당면한 문제는 MQL 문자열에서 C++ char *로의 변환입니다.

내가 뭔가 잘못하고 있는 게 분명해. 아무도 이것을 도울 수 있습니까?

외부 "C"

{

#define MT4_EXPFUNC __declspec(dllexport)

MT4_EXPFUNC int __stdcall messageOrder(문자* 메시지, 정수 길이)

{

노력하다

{

부스트::asio::io_service io_service;

TCP::리졸버 r(io_service);

클라이언트 c(io_service);

//문자 * p;

//문자 메시지[1024];

// 정수 나;

//for(i = 0, p= 메시지; i < 길이; i++, p++)

//{

// 메시지 = *p;

//}

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

표준::문자열 줄 = 메시지;

c.assignMessage(줄);

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

io_service.run();

}

catch(std::exception& e)

{

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

}

반환 0;

}

}

 
revivalfx:
서버에 연결하고 명령을 보내고 닫기 위해 만든 C++ dll에 문제가 있습니다. 나는 boost asio C++ 라이브러리를 사용하고 있으며 웹 사이트에서 예제를 가져왔습니다. 콘솔에서 독립 실행형 실행 파일로 코드를 테스트했으며 원활하게 작동하지만 dll로 변환했을 때 이상한 문자열 잘림 문제가 발생했습니다.

문자열의 첫 번째 문자만 서버에 전달되는 것 같습니다. 현재 테스트 문자열 "get time\n"을 보내고 있지만 메시지가 수신되면 "g"만 표시됩니다.

API는 다음과 같습니다(전체 기능은 아래에 있음).

MT4_EXPFUNC int __stdcall messageOrder(문자* 메시지, 정수 길이)

MQL의 문자열이 실제로 구조라는 것을 읽었고 제안된 MqlStr 구조를 시도했습니다........

구조체 MqlStr

{

int 렌;

문자 *문자열;

};

......하지만 그것도 안되는 것 같습니다. 유효하지 않은 문자열로 서버를 정지시킵니다.

지금까지 "최고"로 작동한 것은 아래에 나열한 것입니다.

아래는 매 틱마다 동일한 문자열을 서버에 보내는 것 외에는 아무것도 하지 않는 테스트 ea입니다.

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

#속성 버전 "1.00"

#속성엄격

#import "Boost.dll";

int messageOrder(문자열 메시지, int 길이);

#수입

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

//| 전문가 초기화 기능 |

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

int OnInit()

{

//---

//---

반환(INIT_SUCCEEDED);

}

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

//| 전문적인 초기화 해제 기능 |

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

무효 OnDeinit(const int 이유)

{

//---

}

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

//| 전문가 틱 기능 |

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

무효 OnTick()

{

//---

문자열 메시지 = "시간 가져오기\n";

//Print("메시지: ", 메시지, " 길이 = ", StringLen(메시지));

messageOrder(메시지, StringLen(메시지));

}

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

dll 내보내기는 아래와 같습니다. 메시지가 수신된 후 std::string을 생성한 다음 해당 문자열을 서버로 보냅니다. 당면한 문제는 MQL 문자열에서 C++ char *로의 변환입니다.

내가 뭔가 잘못하고 있는 게 분명해. 아무도 이것을 도울 수 있습니까?

외부 "C"

{

#define MT4_EXPFUNC __declspec(dllexport)

MT4_EXPFUNC int __stdcall messageOrder(문자* 메시지, 정수 길이)

{

노력하다

{

부스트::asio::io_service io_service;

TCP::리졸버 r(io_service);

클라이언트 c(io_service);

//문자 * p;

//문자 메시지[1024];

// 정수 나;

//for(i = 0, p= 메시지; i < 길이; i++, p++)

//{

// 메시지 = *p;

//}

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

표준::문자열 줄 = 메시지;

c.assignMessage(줄);

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

io_service.run();

}

catch(std::exception& e)

{

std::cerr << "예외: " << 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을 탐색하고 있습니다.

 

데프! 스크립트 아래의 예제를 볼 수 있었던 것 같습니다. 무시. 감사합니다...... 아! 유니코드.

 
revivalfx:
데프! 스크립트 아래의 예제를 볼 수 있었던 것 같습니다. 무시. 감사합니다...... 아! 유니코드.

긴 메시지가 아니었나요?

 

안녕하세요 revalfx님,

char 대신 wchar_t를 사용하고 싶습니다! 나는 같은 문제가 있었다! ;-)

안녕, AT

사유: