Weird issues during DLL expert implementation

 

Hello,

I'm currently developing a DLL expert advisor. I have come across weird issues in MQL4 code, which I hope you'll help me fix.

Firstly, ArrayCopyRates does not seem to work as expected. When I copy the bars to a two-dimensional array, I receive it in a reverse order in my DLL. The nearest time bar in trader has an index of 0, whereas in DLL: (SIZE-1). I do not need a complete bar history in my DLL, as I want to get the nearest time only. I therefore wrote a following code:

double rates[][6], send_rates[][6];

int array_size = ArrayCopyRates(rates);

ArrayResize(send_rates,1);

send_rates[0][0] = rates[0][0];

...

send_rates[0][5] = rates[0][5];

When I print the values in trader, everything seems fine. When I send them to a DLL, it's a mess:

My_DLL_Tick(send_rates,1);

It's OK when I use: My_DLL_Tick(rates,array_size); [At this point the function prints out rates[parameter_2-1][0],...]

Second issue:

What I want to do in init() function is to send some vital platform parameters to my DLL. It's easy when the parameter is an int or double, for example:

My_DLL_Send_Double(AccountBalance());

It becomes a mess when I want to send a string. YES, I use struct MqlStr in my DLL. Static string works fine if I send it as an "artificial" two-dimensional string reference, e.g. string strategy_name[2] = {"MyStrategy"};

My_DLL_Send_String(string& value[]), in this example: My_DLL_Send_String(strategy_name);

This will NOT work if I want to send a "normal" string by value or reference: My_DLL_Send_String(string& value) / My_DLL_Send_String(string value);

This solution crashes when I want to send an AccountCurrency or my current currency:

string account_currency[2] = {AccountCurrency()};

string currency_pair[2] = {Symbol()};

What I get is a compiler error (wow, that's rare!):

'{' - unexpected token

'{' - translator error--out of memory.

I could PROBABLY(?) make this work if I were to send those parameters in start() function, by I don't want to spoil my program's logic: send parameters in init(), work with the bars in start().

How to make this work? Appreciate all of your help!

Cannonball.

 

First: Please read this carefully: http://www.forexfactory.com/showthread.php?t=219576 (although it is in Pascal, it contains all information you need to know, and the code can be literally translated to C)

Strings will be passed just like in C as a simple pointer to the null-terminated buffer, you don't need the MqlStr struct, this is only used when dealing with arrays of string. Also you don't pass the string with &, just pass it by value, it will still pass the pointer to the dll.

mql:

void foo(string baz);

and in C:

void foo(char* baz);


Double and int cannot be passed by reference, only by value, this is a bug in mql4. If you need this then you need to use arrays. Arrays don't need the &, pass them by value, it will pass a pointer anyways and you can always write them from within the dll..

ArrayCopyRates() should be done only once in init(), declare the rates array global, it will automatically be kept up-to-date after once it has been been passes to this function. ArrayCopyRates() will not actually copy anything, it will instead internally mess around with the some internal pointers, making the rates variable point to some dynamically updating memory from this moment on.

the rates array should be passed to the dll as it is, In your DLL the current bar will be Bars-1 (while when accessing it from mql4 it would silently transform the indexing and make it appear as if it were 0 [the same will happen to indicator buffers btw]). But you don't need to worry about this, simply pass the rates array and the bars number to the dll and in the dll you access the last element. Your attempt to copy the data to another array before calling it only slows it down. Passing an array to the function is only passing a pointer, so it does not matter how huge it actually is.

Reason: