Kendi MetaTrader uzantınızı (dll) oluşturun - sayfa 14

 

Merhaba Mladen!

[0] arabelleğinin değerini almaya çalıştığımda, değer Tampon: 2147483647 gibi bir şey

Yani bunun doğru olmadığını düşünüyorum... Şöyle bir değer olmalı: 1,23584

bir test yapıp belirlediğim gibi: buffer = Rates[10].close;

Herhangi bir fikir?

Çok teşekkürler ve hoşçakal, AT

 
at120:
Merhaba Mladen!

[0] arabelleğinin değerini almaya çalıştığımda, değer Tampon: 2147483647 gibi bir şey

Yani bunun doğru olmadığını düşünüyorum... Şöyle bir değer olmalı: 1,23584

bir test yapıp belirlediğim gibi: buffer = Rates[10].close;

Herhangi bir fikir?

Çok teşekkürler ve hoşçakal, AT

Bu değerler, EMPTY_VALUE olarak bilinir

Mql tarafından arabellek bildiriminiz ve değer atamanızla ilgili her şeyin yolunda olup olmadığını kontrol edin. Ayrıca bir C++ tarafından arabellek (dizi) öğelerini nasıl ele aldığınızı kontrol edin.

 

Merhaba Mladen!

DLL'yi çağırırken ve ayrıca arabelleklerle bir şeyler denedim, ANCAK herhangi bir pozitif sonuç olmadan ...

C++ kodundaki arabellek değerini 1 olarak ayarlamaya çalıştım, arabellek[]=1; Değişiklik yok...

Aşağıdaki MQL4 koduyla çağırdığım DLL'yi (lütfen .zip do .dll'den yeniden adlandırın) ekledim

Herhangi bir girdi/ipucu için teşekkürler...

hoşçakal, 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);

}
Dosyalar:
 
at120:
Merhaba Mladen!

DLL'yi çağırırken ve ayrıca arabelleklerle bir şeyler denedim, ANCAK herhangi bir pozitif sonuç olmadan ...

C++ kodundaki arabellek değerini 1 olarak ayarlamaya çalıştım, arabellek[]=1; Değişiklik yok...

Aşağıdaki MQL4 koduyla çağırdığım DLL'yi (lütfen .zip do .dll'den yeniden adlandırın) ekledim

Herhangi bir girdi/ipucu için teşekkürler...

hoşçakal, 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);

}

tampon[]=1; - mql'de hiçbir şey ifade etmez. Buffer[] bölümünde bir indeks kullanmanız gerekir (buffer[0]=1; gibi)

 

Merhaba Mladen!

Aşağıdakileri C++ 'da kullandım

arabellek = 1;

Yani bu normalde çalışması gerekir ...

C++ kodu aşağıdaki gibi görünür.

Yardım için teşekkürler!!

hoşçakal, 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

 

Bir sunucuya bağlanmak, komut göndermek ve kapatmak için oluşturduğum bir c++ dll ile ilgili bir sorun yaşıyorum. Boost asio C++ kitaplıklarını kullanıyorum ve web sitelerinden bir örnek aldım. Kodu konsolda bağımsız bir yürütülebilir dosya olarak test ettim ve sorunsuz çalışıyor, ancak onu bir dll'ye dönüştürdüğümde garip bir dize kesme sorunu görüyorum.

Yalnızca dizedeki ilk karakter sunucuya iletiliyor gibi görünüyor. Şu anda bir test dizesi "get time\n" gönderiyorum, ancak mesaj alındığında yalnızca "g" görünüyor.

API şöyle görünür (tam işlev aşağıdadır):

MT4_EXPFUNC int __stdcall messageOrder(char* mesaj, int uzunluk)

MQL'deki dizenin aslında bir yapı olduğunu okudum ve önerilen MqlStr yapısını denedim, .......

yapı MqlStr

{

int len;

karakter *dizisi;

};

...... ama bu da işe yaramıyor. Geçersiz bir dize ile sunucuyu kilitler.

Şimdiye kadar "en iyi" işe yarayan, aşağıda listelediklerimdir.

Aşağıda, her tikte sunucuya aynı dizgiyi göndermekten başka bir şey yapmayan benim test ea'm var.

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

#özellik sürümü "1.00"

#mülkiyet katı

#import "Boost.dll";

int messageOrder(string mesaj, int uzunluk);

#içe aktarmak

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

//| Uzman başlatma işlevi |

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

int OnInit()

{

//---

//---

dönüş(INIT_SUCCEEDED);

}

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

//| Uzman başlatmasızlaştırma işlevi |

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

geçersiz OnDeinit(const int nedeni)

{

//---

}

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

//| Uzman onay işlevi |

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

geçersiz OnTick()

{

//---

string mesaj = "zaman al\n";

//Print("mesaj: ", mesaj, " uzunluk = ", StringLen(mesaj));

mesajSiparişi(mesaj, StringLen(mesaj));

}

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

Dll ihracatı aşağıdadır. Mesaj alındıktan sonra bir std::string oluşturuyorum ve ardından bu stringi sunucuya gönderiyorum. Eldeki sorun, MQL dizesini C++ char * dönüştürmesidir.

Belli ki yanlış bir şey yapıyorum. Bu konuda yardımcı olabilecek var mı?

dış "C"

{

#define MT4_EXPFUNC __declspec(dllexport)

MT4_EXPFUNC int __stdcall messageOrder(char* mesaj, int uzunluk)

{

denemek

{

boost::asio::io_service io_service;

tcp::resolver r(io_service);

istemci c(io_service);

// karakter * p;

//karakter mesajı[1024];

//int ben;

//for(i = 0, p= mesaj; i < uzunluk; i++, p++)

//{

// mesaj = *p;

//}

//std::string satır = std::string(msg);

std::string satır = mesaj;

c.assignMessage(satır);

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

io_service.run();

}

yakalamak (std::istisna ve e)

{

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

}

0 döndür;

}

}

 
revivalfx:
Bir sunucuya bağlanmak, komut göndermek ve kapatmak için oluşturduğum bir c++ dll ile ilgili bir sorun yaşıyorum. Boost asio C++ kitaplıklarını kullanıyorum ve web sitelerinden bir örnek aldım. Kodu konsolda bağımsız bir yürütülebilir dosya olarak test ettim ve sorunsuz çalışıyor, ancak onu bir dll'ye dönüştürdüğümde garip bir dize kesme sorunu görüyorum.

Yalnızca dizedeki ilk karakter sunucuya iletiliyor gibi görünüyor. Şu anda bir test dizesi "get time\n" gönderiyorum, ancak mesaj alındığında yalnızca "g" görünüyor.

API şöyle görünür (tam işlev aşağıdadır):

MT4_EXPFUNC int __stdcall messageOrder(char* mesaj, int uzunluk)

MQL'deki dizenin aslında bir yapı olduğunu okudum ve önerilen MqlStr yapısını denedim, .......

yapı MqlStr

{

int len;

karakter *dizisi;

};

...... ama bu da işe yaramıyor. Geçersiz bir dize ile sunucuyu kilitler.

Şimdiye kadar "en iyi" işe yarayan, aşağıda listelediklerimdir.

Aşağıda, her tikte sunucuya aynı dizgiyi göndermekten başka hiçbir şey yapmayan benim test ea'm var.

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

#özellik sürümü "1.00"

#mülkiyet katı

#import "Boost.dll";

int messageOrder(string mesaj, int uzunluk);

#içe aktarmak

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

//| Uzman başlatma işlevi |

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

int OnInit()

{

//---

//---

dönüş(INIT_SUCCEEDED);

}

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

//| Uzman başlatmasızlaştırma işlevi |

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

geçersiz OnDeinit(const int nedeni)

{

//---

}

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

//| Uzman onay işlevi |

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

geçersiz OnTick()

{

//---

string mesaj = "zaman al\n";

//Print("mesaj: ", mesaj, " uzunluk = ", StringLen(mesaj));

mesajSiparişi(mesaj, StringLen(mesaj));

}

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

Dll ihracatı aşağıdadır. Mesaj alındıktan sonra bir std::string oluşturuyorum ve ardından bu stringi sunucuya gönderiyorum. Eldeki sorun, MQL dizesini C++ char * dönüştürmesidir.

Belli ki yanlış bir şey yapıyorum. Bu konuda yardımcı olabilecek var mı?

dış "C"

{

#define MT4_EXPFUNC __declspec(dllexport)

MT4_EXPFUNC int __stdcall messageOrder(char* mesaj, int uzunluk)

{

denemek

{

boost::asio::io_service io_service;

tcp::resolver r(io_service);

istemci c(io_service);

// karakter * p;

//karakter mesajı[1024];

//int ben;

//for(i = 0, p= mesaj; i < uzunluk; i++, p++)

//{

// mesaj = *p;

//}

//std::string satır = std::string(msg);

std::string satır = mesaj;

c.assignMessage(satır);

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

io_service.run();

}

yakalamak (std::istisna ve e)

{

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

}

0 döndür;

}

}

Görünüşe göre MqlStr yapısını kullanırken onu uygunsuz şekilde açıyordum.

Şimdi yapıyorum:

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

}

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

Şimdi daha önceki bir gönderideki bir bağlantıya dayanarak bir C# DLL'sini araştırıyorum.

 

derp! Sanırım betiklerin altındaki örneğe bakabilirdim. önemsememek. Teşekkürler...... Ah! Unicode.

 
revivalfx:
derp! Sanırım betiklerin altındaki örneğe bakabilirdim. önemsememek. Teşekkürler...... Ah! Unicode.

Bu uzun bir mesaj değil miydi?

 

Merhaba revalfx,

char'ın wchar_t instadını kullanmak istiyorsun! Ben de aynı sorunu yaşadım! ;-)

hoşçakal, AT

Neden: