How do I pass a timeseries array to a DLL?

 

Hi,


I've been experimenting with passing different types of MQL4 data types to a C++ DLL and have found something I think is a bit odd.


If I define an array of double's as follows

double myArray[3] = { 1.2, 3.2, 1.3 };


I can pass this by reference or by value to my C function

MT4_EXPFUNC void __stdcall DumpArrayOfDoubles(const double *dVals, const int iNumVals) {


and iterate through the elements in the array without any problem.


However, if I try to pass one of the MQL4 timeseries arrays, such as Close, e.g.


DumpArrayOfDoubles(Close, 10);


then when I check the array in my C function, it is NULL.


What am I doing wrong here? What is the difference between an arry that I define and an array that is provided by the MQL4 runtime?

 
mjbrady:

What am I doing wrong here? What is the difference between an arry that I define and an array that is provided by the MQL4 runtime?

I don't know, but my personal guess is that Close[] is a sort of virtual array, and actually gets interpreted by MQL more like a function. That would be a sensible security measure. Otherwise, if you could pass the Close[] array to a DLL, then a DLL could overwrite the contents of the array, corrupting the historic close data for the entire platform - whether accidentally or deliberately.


I think your only option is to copy data from Close[] into an array of your own, and then pass that to the DLL.

 
If Close[] becomes a special array, then the solution may be to dump it into a new array, then pass it into your DLL array dump function.
 

Thanks for the replies. I agree it is most likely a virtual object of some kind, so thats why I can't pass it.


What would be really cool is to be able to either

a) call back into the MQL4 environment from the DLL, or

b) pass a kind of function pointer across from MQL4 to the DLL....but this is just wishful thinking.


For information, I had already tried what you suggested (i.e. copy the array) and this works just fine. Its just that I have a dislike of copying data around in that manner, particularly if I need to do it regularly, like on every tick.

 
mjbrady:

What would be really cool is to be able to either [...]

I doubt you'll get either of these even in MT5. Depending on context, the best workaround is usually to have a DLL maintain a queue of things it wants to communicate to the EA, and to force calls to the EA's start() function when it wants to talk.


just that I have a dislike of copying data around in that manner, particularly if I need to do it regularly, like on every tick.

If you're dealing with things like an array of close prices, why do you need to do a full copy on every tick? You could declare the array as static, only re-create it in full when a new bar starts (i.e. at most once per minute, not once per tick), and between times you simply update the latest close price in the array.

 
jjc:

Depending on context, the best workaround is usually to have a DLL maintain a queue of things it wants to communicate to the EA, and to force calls to the EA's start() function when it wants to talk.

 
mjbrady:

Sorry, finger trouble. What I wanted to know more about is how to force calls to the EA start() function from within the DLL?


Also, your suggestion to pass a copy of the array just once, and thereafter just maintain it is a good one. Thanks for that.

 
jjc:

If you're dealing with things like an array of close prices, why do you need to do a full copy on every tick? You could declare the array as static, only re-create it in full when a new bar starts (i.e. at most once per minute, not once per tick), and between times you simply update the latest close price in the array.

Why should one copy the whole array more than once? The array data doesn't change only the latest close price changes on a tick. Copy the array once at initialisation then just update the latest prices and move the pointer to the latest price in a cyclic buffer that way you only transfer HOCL once a minute and Close on every tick.

 
Ruptor:

Why should one copy the whole array more than once? [...] just update the latest prices and move the pointer to the latest price in a cyclic buffer

Because a cyclical buffer requires extra logic in the EA and in the DLL. For example, an ATR-like calculation in the DLL would become much more complicated if the data wraps round. Given that an array copy is a simple memory blit, the complexities of dealing with a cyclical buffer are very likely to use more processor cycles than just doing an occasional re-copy of the array. And, IMHO, it just isn't worth the extra coding complexity to save a few nanoseconds on an operation which happens at most once per minute.

 
mjbrady:

What I wanted to know more about is how to force calls to the EA start() function from within the DLL?

See 'Execute EA without waiting for a tick?'. Basically, you use the Windows API to post a message to the chart's window.

 
jjc:

Because a cyclical buffer requires extra logic in the EA and in the DLL. For example, an ATR-like calculation in the DLL would become much more complicated if the data wraps round. Given that an array copy is a simple memory blit, the complexities of dealing with a cyclical buffer are very likely to use more processor cycles than just doing an occasional re-copy of the array. And, IMHO, it just isn't worth the extra coding complexity to save a few nanoseconds on an operation which happens at most once per minute.

I' sorry but I don't think you understand what a cyclic buffer is so let me explain. It is just an array of say 1000 candle close values that is initialised when the EA starts hence one complete copy is required and that's it. From now on you just take the current close value and write it at the pointer postion which at the start will be [0]. When the next candle time occurs all you do is increment the pointer check if it is greater than 1000 and if so set it to 0 and startt writting the next close values until the next candle time is finished. So how can this be more complicated or slower than copy th whole array every time. One copy of the array is 1000 reads 1000 writes and 1000 checks plus all the other house keeping the system does. My back ground is low level embedded coding with a lot of assembler involved to reduce processor operating cycles so believe me the cyclic buffer is a solution that involves the minimum of CPU time. Cyclic buffers are extenvsively used in codec programming for high speed systems because it reduces data shuffling only requiring an update of the pointer.

Reason: