(Resolved) I§m confused: passing double array to dll

 

It's my third post with the same question.

Yes I have obtain appropriate response, but no one real example.

So, i haved test all (and also the absurd) possibilities:



So, my question is simple:

What i do wrong? because i really don't know.

Thanks for all sugestion.

extern "C"
{
#endif

void __stdcall DLL_EXPORT exportdoublearr(double* value, int* size);

#ifdef __cplusplus
}
template<typename T>
std::string to_string( const T & Value )
{
    std::ostringstream oss;
    oss << Value;
    return oss.str();
}

---


void DLL_EXPORT exportdoublearr(double * value, int* size)
{
    int sz;

    ofstream outputFile2("C:\\program4data.txt",ios_base::app);
    outputFile2<<"perm ligne, val 0:"<<endl;

    sz = size[0];
    outputFile2<<"svcnd ligne> "<<to_string(sz)<<endl;
    if (value == NULL) outputFile2<<"value==NULL"<<endl;
    for(int x=3; x<sz; x++)
    {
        outputFile2<<to_string(value[x])<<endl;
    }
    outputFile2.close();
}

 #import "mt4_dll1.dll"
   void      exportdoublearr(double & value[], int & size[]);
 #import
#include <tstdll1.mqh>
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
   int sz[1]={0};
   double val[];
   sz[0] = ArrayCopySeries(val, MODE_OPEN, Symbol(), PERIOD_H1);

   int sz2[1];
   sz2[0] = ArraySize(val);

   exportdoublearr(val, sz2);

   return(0);
  }
 

why are you passing the size as an array? It is just one number, pass it as an int (no * and no &, just an ordinary int).


the array itself is a (double * value) and on mql4 side it is a (double &value[]), so this is correct. mql4 will pass a pointer to the memory block containing all the double values.


mql4:

#import foo.dll

void foobar(double &val[], int size);

#import



and in C:

void foobar(double * val, int size)

/* make sure this will be exported as __stdcall (the default is __cdecl but cdecl would make it crash as soon as you try to call it from mt4, I don't know the exact needed syntax for your compiler to make this happen, look into the manual or at the other examples) */



or in Pascal:

procedure foobar(val: PDouble; size: LongInt); stdcall;

 

"why are you passing the size as an array?"

because: https://docs.mql4.com/basis/variables/extfunctions
" If there is a need to pass data of the int or double type, then the one-dimensional array of the corresponding type should be passed by reference as a parameter."


Many thanks to your answer, but as you can see on the screenshot on line 19-21....., so i conclude that the error si on the acces call of the stored value.

How to obtain it if any of this three possibilities don't work:

double var = value[x];
double var = *value[x];
double var = &value[x];

?

 
plukamars:

"why are you passing the size as an array?"

because: https://docs.mql4.com/basis/variables/extfunctions
" If there is a need to pass data of the int or double type, then the one-dimensional array of the corresponding type should be passed by reference as a parameter."

This is only relevant if you want to pass variables by reference. The documentation is a bit confusig and it seems they left out some explanation (maybe some things got lost during translation from russian to english). At the top of the page there are examples where they call into the windows API with int by value. Due to a shortcoming (bug) of mql4 you cannot pass double or int by reference, only by value (you can pass them to other mql4 functions by reference but not to imported DLL functions for some strange reason). In this case you would need to use the trick with the one-element array.

But in *your* specific application the size parameter does not need to be passed by reference, so you don't have to jump through these hoops at all, you can simply pass it by value and by value works out of the box without any tricks.


The syntax I mentioned in my previous post is correct, if you are experiencing errors then there must be another reason.


PS:

Maybe you should not try to start your programming career directly with C++ (which really requires the black belt of programming to truly understand what you are doing) and instead start with something friendlier with a less confusing syntax and a more type-safe (and thus more helpful) compiler like Pascal. Pascal would help you acquire the knowledge about the needed data structures (machine native data types, pointers, arrays, records (structs), objects, etc.) in a much less frustrating way and this knowledge can then later be used 1:1 for C++ programming (because both languages are static typed and use the same primitives to operate on the data, only the syntax of pascal is much cleaner, more expressive and less confusing). FPC is a modern and highly optimizing Pascal compiler that does not have to hide behind C++ in any way, it has all needed language features to be a full replacement and in some regards it is even light-years ahead of C++. See the Lazarus/FPC thread in the forexfactory forum for how to use it to make MT4 DLLs.

 

One more tip:

If you can find one of the older MT4 builds (from a few years ago, ask on the forum maybe someone can point you to a download) these older builds don't yet have this stupid anti-debugger nonsense built into them.

You can then simply attach a debugger, set breakpoints, single-step your function call while closely observing the stack, the the CPU registers (stack pointer) and the function arguments on the stack and/or the memory they point to when your function is entered and when it returns. This should give you further clues about what exactly is going on and it is generally very educative to see how the compiled code and the function calls actually work under the hood. Knowing what kind of things are actually going on on the machine language level is essential knowledge for C++ and will answer many of your questions.

Another helpful advise would be to make use of the OutputDebugString() function of the windows API in conjunction with a tool like DebugView.exe as a replacement for print inside your DLL (you cannot simply printf() to the console becaue there is no console and no stdout available). You could then output the contents of variables at various places inside your DLL function to be able to better observe and understand what is going on (or going wrong) in your function.

 

Yes i haved think about old version. To tell the true the script is running on the version of a broker and not the native version of metaquote.

I'm not novice in c++. I have made the table of combination because all "logic" possibilities don't run... i will test with other and older version (i haved one from 3 year ago somethere in a fergot hdd :] ).

I haved think about other language, but the i start with programming, i haved read maz documentation to find witch language i will used as primairy, and after 2 month the list contain only c and c++, so i haved speak with co-workers, and c++ haved win with 86%......

 

ok, i have study some file, fight with my ide and compiler settings, and with an downloaded example i don't have any error.

So i have just to analyse the difference to understand why... ouf

Thanks for your help 7bit

 
ah, okay..
is not a problem of programation, but of used fonction in mql to init the array...
aneb how to kill 2 days...
 
plukamars:

Yes i haved think about old version. To tell the true the script is running on the version of a broker and not the native version of metaquote.


I meant *really* old versions, that let you attach a debugger. The newer ones (from around 2010 and later, i don't know the exact version number when they started with this nonsense) have this useless anti-debugger "protection" built in which will prevent you from debugging. It doesn't affect how it runs when it runs but being able to use a debugger and also having meaningful stack traces when it crashes is much better for development.
 
7bit:
Another helpful advise would be to make use of the OutputDebugString() function of the windows API in conjunction with a tool like DebugView.exe as a replacement for print inside your DLL
The advantage of OutputDebugString is it can be used in both the DLL and MQL4: Better alternative for Print() for debugging @ Forex Factory
 
WHRoeder:
The advantage of OutputDebugString is it can be used in both the DLL and MQL4: Better alternative for Print() for debugging @ Forex Factory



oh, i will stor this usefull info for later, thanks
Reason: