Create your own MetaTrader extension (dll) - page 14

 
at120:
Hi Mladen!

When I try to get the value of the buffer[0] the value is something like Buffer: 2147483647

So I think this is not right... There should be a value something like: 1,23584

as I made a test and set: buffer = Rates[10].close;

Any ideas?

Thanks a lot and bye, AT

That values is what is known as EMPTY_VALUE

From mql side check if all is OK with your buffer declaration and values assignment. Also check how are you handling buffer (array) elements from a C++ side

 

Hi Mladen!

I tried something in calling the DLL and also with buffers, BUT without any positiv results...

I tried to set the buffer value in the C++ code to 1, buffer[]=1; No change...

I attched the DLL (please just rename it from .zip do .dll), which I call with the following MQL4 code

Thanks for any inputs/hints...

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

}
Files:
 
at120:
Hi Mladen!

I tried something in calling the DLL and also with buffers, BUT without any positiv results...

I tried to set the buffer value in the C++ code to 1, buffer[]=1; No change...

I attched the DLL (please just rename it from .zip do .dll), which I call with the following MQL4 code

Thanks for any inputs/hints...

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

}

You can not use buffer[]=1; - it means nothing in mql. You have to use some index in the buffer[] part (like buffer[0]=1; )

 

Hi Mladen!

I used the following for it in C++

buffer = 1;

So this should normaly work...

The C++ code looks like below.

Thanks for help!!

Bye, 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

 

I'm having an issue with a c++ dll that I created to connect to a server, send commands and close. I am using the boost asio C++ libraries and took an example from their website. I tested the code as a stand alone executable in the console and it works swimmingly, but when I converted it to a dll, that's where I am seeing a weird string truncation issue.

Only the first character in the string seems to get passed to the server. Currently I am sending a test string "get time\n" but only "g" is seen when the message is received.

The API looks like this (the full function is below):

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

I've read that the string in MQL is actually a structure and I've tried the MqlStr structure that was suggested,.......

struct MqlStr

{

int len;

char *string;

};

...... but that doesn't seem to work, either. It hangs the server with an invalid string.

What has worked the "best" so far is what I have listed below.

Below is my test ea that does nothing but send the same string to the server every tick.

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

#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()

{

//---

string message = "get time\n";

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

messageOrder(message, StringLen(message));

}

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

The dll export is below. I am creating a std::string after the message is received and then sending that string to the server. The issue at hand is the MQL string to C++ char * conversion.

I'm obviously doing something wrong. Can anyone help with this?

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:
I'm having an issue with a c++ dll that I created to connect to a server, send commands and close. I am using the boost asio C++ libraries and took an example from their website. I tested the code as a stand alone executable in the console and it works swimmingly, but when I converted it to a dll, that's where I am seeing a weird string truncation issue.

Only the first character in the string seems to get passed to the server. Currently I am sending a test string "get time\n" but only "g" is seen when the message is received.

The API looks like this (the full function is below):

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

I've read that the string in MQL is actually a structure and I've tried the MqlStr structure that was suggested,.......

struct MqlStr

{

int len;

char *string;

};

...... but that doesn't seem to work, either. It hangs the server with an invalid string.

What has worked the "best" so far is what I have listed below.

Below is my test ea that does nothing but send the same string to the server every tick.

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

#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()

{

//---

string message = "get time\n";

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

messageOrder(message, StringLen(message));

}

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

The dll export is below. I am creating a std::string after the message is received and then sending that string to the server. The issue at hand is the MQL string to C++ char * conversion.

I'm obviously doing something wrong. Can anyone help with this?

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;

}

}

As it turns out when I was using the MqlStr struct I was unpacking it improperly.

Now I am doing:

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

}

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

I am now exploring a C# DLL instead based on a link in an earlier post.

 

derp! I guess I coulda looked at the example under scripts. disregard. Thanks...... Ah! Unicode.

 
revivalfx:
derp! I guess I coulda looked at the example under scripts. disregard. Thanks...... Ah! Unicode.

Wasn't that a length of a message?

 

Hi revalfx,

You want to use wchar_t instad of char! I had the same problem! ;-)

Bye, AT

 

Compiling DLLSample.cpp generates 27 unresolved external symbols.

Why?

How to fix this?

Where should DLL files be placed for mq4 to find them?

Reason: