Erstellen Sie Ihre eigene MetaTrader-Erweiterung (dll) - Seite 14

 

Hallo Mladen!

Wenn ich versuche, den Wert des Puffers[0] zu erhalten, ist der Wert ungefähr so wie Buffer: 2147483647

Ich denke also, dass dies nicht richtig ist... Es sollte ein Wert sein wie: 1,23584

Ich habe einen Test gemacht und gesetzt: buffer = Rates[10].close;

Irgendwelche Ideen?

Vielen Dank und auf Wiedersehen, AT

 
at120:
Hallo Mladen!

Wenn ich versuche, den Wert des Puffers[0] abzurufen, lautet der Wert in etwa Puffer: 2147483647

Ich denke also, dass dies nicht richtig ist... Es sollte einen Wert geben, der ungefähr so aussieht: 1,23584

Ich habe einen Test gemacht und gesetzt: buffer = Rates[10].close;

Hat jemand eine Idee?

Vielen Dank und auf Wiedersehen, AT

Dieser Wert ist als EMPTY_VALUE bekannt.

Überprüfen Sie auf der MQL-Seite, ob Ihre Pufferdeklaration und die Zuweisung der Werte in Ordnung sind. Prüfen Sie auch, wie Sie die Puffer (Array)-Elemente von einer C++-Seite aus behandeln

 

Hallo Mladen!

Ich habe etwas beim Aufruf der DLL und auch mit Puffern versucht, ABER ohne positive Ergebnisse...

Ich habe versucht, den Pufferwert im C++ Code auf 1 zu setzen, buffer[]=1; Keine Änderung...

Ich habe die DLL angehängt (bitte benennen Sie sie einfach von .zip in .dll um), die ich mit dem folgenden MQL4-Code aufrufe

Vielen Dank für alle Anregungen/Hinweise...

Tschüss, 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);

}
Dateien:
 
at120:
Hallo Mladen!

Ich versuchte etwas in den Aufruf der DLL und auch mit Puffern, ABER ohne positive Ergebnisse...

Ich habe versucht, den Pufferwert im C++-Code auf 1 zu setzen, buffer[]=1; Keine Änderung...

Ich habe die DLL angehängt (bitte benennen Sie sie einfach von .zip in .dll um), die ich mit dem folgenden MQL4-Code aufrufe

Vielen Dank für alle Anregungen/Hinweise...

Tschüss, 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);

}

Sie können nicht verwenden buffer[]=1; - es bedeutet nichts in MQL. Sie müssen einen Index im buffer[]-Teil verwenden (wie buffer[0]=1; )

 

Hallo Mladen!

Ich habe dafür in C++ folgendes verwendet

Puffer = 1;

Das sollte also normalerweise funktionieren...

Der C++ Code sieht wie unten aus.

Danke für die Hilfe!!

Tschüss, 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

 

Ich habe ein Problem mit einer C++-DLL, die ich erstellt habe, um eine Verbindung zu einem Server herzustellen, Befehle zu senden und zu schließen. Ich verwende die boost asio C++-Bibliotheken und nahm ein Beispiel von ihrer Website. Ich habe den Code als eigenständige ausführbare Datei in der Konsole getestet und er funktioniert einwandfrei, aber als ich ihn in eine DLL konvertiert habe, trat ein seltsames Problem mit der Stringabschneidung auf.

Nur das erste Zeichen in der Zeichenfolge scheint an den Server weitergeleitet zu werden. Derzeit sende ich eine Testzeichenfolge "get time\n", aber beim Empfang der Nachricht wird nur "g" angezeigt.

Die API sieht wie folgt aus (die vollständige Funktion finden Sie unten):

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

Ich habe gelesen, dass der String in MQL eigentlich eine Struktur ist, und ich habe die MqlStr-Struktur ausprobiert, die vorgeschlagen wurde: .......

struct MqlStr

{

int len;

char *string;

};

...... aber auch das scheint nicht zu funktionieren. Der Server bleibt mit einer ungültigen Zeichenkette hängen.

Was bisher am "besten" funktioniert hat, ist das, was ich unten aufgeführt habe.

Unten ist meine Test-Ea, die nichts anderes tut, als bei jedem Tick denselben String an den Server zu senden.

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

#property version "1.00"

#property strict

#import "Boost.dll";

int messageOrder(string message, int length);

#import

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

//| Experten-Initialisierungsfunktion |

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

int OnInit()

{

//---

//---

return(INIT_SUCCEEDED);

}

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

//| Experten-Deinitialisierungsfunktion |

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

void OnDeinit(const int reason)

{

//---

}

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

//| Expert tick function |

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

void OnTick()

{

//---

string message = "get time\n";

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

messageOrder(message, StringLen(message));

}

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

Der dll-Export ist unten zu sehen. Ich erstelle einen std::string, nachdem die Nachricht empfangen wurde, und sende diesen String dann an den Server. Das Problem ist die MQL-String zu C++ char * Umwandlung.

Ich mache offensichtlich etwas falsch. Kann mir jemand dabei helfen?

extern "C"

{

#define MT4_EXPFUNC __declspec(dllexport)

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

{

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);

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";

}

return 0;

}

}

 
revivalfx:
Ich habe ein Problem mit einer C++-DLL, die ich erstellt, um eine Verbindung zu einem Server, Befehle senden und schließen. Ich verwende die boost asio C++ Bibliotheken und habe ein Beispiel von deren Website genommen. Ich testete den Code als eigenständige ausführbare Datei in der Konsole und es funktioniert schwimmend, aber wenn ich es in eine DLL konvertiert, das ist, wo ich eine seltsame String-Trunkierung Problem zu sehen sind.

Nur das erste Zeichen der Zeichenfolge scheint an den Server weitergeleitet zu werden. Derzeit sende ich eine Testzeichenfolge "get time\n", aber beim Empfang der Nachricht wird nur "g" angezeigt.

Die API sieht wie folgt aus (die vollständige Funktion finden Sie unten):

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

Ich habe gelesen, dass der String in MQL eigentlich eine Struktur ist, und ich habe die MqlStr-Struktur ausprobiert, die vorgeschlagen wurde: .......

struct MqlStr

{

int len;

char *string;

};

...... aber auch das scheint nicht zu funktionieren. Der Server bleibt mit einer ungültigen Zeichenkette hängen.

Was bisher am "besten" funktioniert hat, ist das, was ich unten aufgeführt habe.

Unten ist meine Test-Ea, die nichts anderes tut, als bei jedem Tick denselben String an den Server zu senden.

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

#property version "1.00"

#property strict

#import "Boost.dll";

int messageOrder(string message, int length);

#import

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

//| Experten-Initialisierungsfunktion |

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

int OnInit()

{

//---

//---

return(INIT_SUCCEEDED);

}

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

//| Experten-Deinitialisierungsfunktion |

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

void OnDeinit(const int reason)

{

//---

}

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

//| Expert tick function |

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

void OnTick()

{

//---

string message = "get time\n";

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

messageOrder(message, StringLen(message));

}

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

Der dll-Export ist unten zu sehen. Ich erstelle einen std::string, nachdem die Nachricht empfangen wurde, und sende diesen String dann an den Server. Das Problem ist die MQL-String zu C++ char * Umwandlung.

Ich mache offensichtlich etwas falsch. Kann mir jemand dabei helfen?

extern "C"

{

#define MT4_EXPFUNC __declspec(dllexport)

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

{

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);

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";

}

return 0;

}

}

Wie sich herausstellte, habe ich die MqlStr-Struktur nicht richtig entpackt, als ich sie verwendete.

Das tue ich jetzt:

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);

}

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

Ich untersuche jetzt stattdessen eine C#-DLL, basierend auf einem Link in einem früheren Beitrag.

 

Dumm gelaufen! Ich schätze, ich hätte mir das Beispiel unter Skripte ansehen können. ignorieren. Danke...... Ah! Unicode.

 
revivalfx:
Mist! Ich schätze, ich hätte mir das Beispiel unter Skripte ansehen können. ignorieren. Danke...... Ah! Unicode.

War das nicht die Länge einer Nachricht?

 

Hallo revalfx,

Du willst wchar_t anstelle von char verwenden! Ich hatte das gleiche Problem! ;-)

Tschüss, AT