서버에 연결하고 명령을 보내고 닫기 위해 만든 C++ dll에 문제가 있습니다. 나는 boost asio C++ 라이브러리를 사용하고 있으며 웹 사이트에서 예제를 가져왔습니다. 콘솔에서 독립 실행형 실행 파일로 코드를 테스트했으며 원활하게 작동하지만 dll로 변환했을 때 이상한 문자열 잘림 문제가 발생했습니다.
문자열의 첫 번째 문자만 서버에 전달되는 것 같습니다. 현재 테스트 문자열 "get time\n"을 보내고 있지만 메시지가 수신되면 "g"만 표시됩니다.
API는 다음과 같습니다(전체 기능은 아래에 있음).
MT4_EXPFUNC int __stdcall messageOrder(문자* 메시지, 정수 길이)
MQL의 문자열이 실제로 구조라는 것을 읽었고 제안된 MqlStr 구조를 시도했습니다........
구조체 MqlStr
{
int 렌;
문자 *문자열;
};
......하지만 그것도 안되는 것 같습니다. 유효하지 않은 문자열로 서버를 정지시킵니다.
지금까지 "최고"로 작동한 것은 아래에 나열한 것입니다.
다음은 매 틱마다 동일한 문자열을 서버에 보내는 것 외에는 아무것도 하지 않는 테스트 ea입니다.
revivalfx: 서버에 연결하고 명령을 보내고 닫기 위해 만든 C++ dll에 문제가 있습니다. 나는 boost asio C++ 라이브러리를 사용하고 있으며 웹 사이트에서 예제를 가져왔습니다. 콘솔에서 독립 실행형 실행 파일로 코드를 테스트했으며 원활하게 작동하지만 dll로 변환했을 때 이상한 문자열 잘림 문제가 발생했습니다.
문자열의 첫 번째 문자만 서버에 전달되는 것 같습니다. 현재 테스트 문자열 "get time\n"을 보내고 있지만 메시지가 수신되면 "g"만 표시됩니다.
API는 다음과 같습니다(전체 기능은 아래에 있음).
MT4_EXPFUNC int __stdcall messageOrder(문자* 메시지, 정수 길이)
MQL의 문자열이 실제로 구조라는 것을 읽었고 제안된 MqlStr 구조를 시도했습니다........
구조체 MqlStr
{
int 렌;
문자 *문자열;
};
......하지만 그것도 안되는 것 같습니다. 유효하지 않은 문자열로 서버를 정지시킵니다.
지금까지 "최고"로 작동한 것은 아래에 나열한 것입니다.
아래는 매 틱마다 동일한 문자열을 서버에 보내는 것 외에는 아무것도 하지 않는 테스트 ea입니다.
안녕 믈라덴!
buffer[0] 값을 얻으려고 할 때 값은 Buffer: 2147483647과 같습니다.
그래서 나는 이것이 옳지 않다고 생각합니다... 다음과 같은 값이 있어야 합니다: 1,23584
내가 테스트하고 설정했을 때: buffer = Rates[10].close;
어떤 아이디어?
감사합니다. AT
안녕 믈라덴!
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_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);
}안녕 믈라덴!
DLL을 호출하고 버퍼를 사용하여 무언가를 시도했지만 긍정적 인 결과가 없었습니다 ...
C++ 코드의 버퍼 값을 1로 설정하려고 했습니다. buffer[]=1; 변경 없음...
다음 MQL4 코드로 호출하는 DLL을 첨부했습니다(.zip do .dll에서 이름을 바꾸십시오).
모든 입력/힌트에 감사드립니다...
안녕, AT
sma_rec.dll.zip
#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;
}
}
서버에 연결하고 명령을 보내고 닫기 위해 만든 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을 탐색하고 있습니다.
데프! 스크립트 아래의 예제를 볼 수 있었던 것 같습니다. 무시. 감사합니다...... 아! 유니코드.
데프! 스크립트 아래의 예제를 볼 수 있었던 것 같습니다. 무시. 감사합니다...... 아! 유니코드.
긴 메시지가 아니었나요?
안녕하세요 revalfx님,
char 대신 wchar_t를 사용하고 싶습니다! 나는 같은 문제가 있었다! ;-)
안녕, AT