C++ DLL function problem - crashing when int arg is passed

 

Hi:


I am hoping that someone can help me.


When I try to execute a simple function from a DLL that accepts an int argument, MQL4 crashes with no stack trace.


Here is the crash dump. As you can see, there is no stack trace but that is okay because I know exactly where it is happening. I just can't figure out why.


There has been a critical error
Time        : 2009.01.17 19:11
Program     : Client Terminal
Version     : 4.00 (build: 220, 7 Nov 2008)
OS          : Windows XP Professional 5.1 Service Pack 3 (Build 2600)
Processors  : 1 x X86 (level 15)
Memory      : 2097151/2030532 kb
Exception   : C0000005
Address     : 00000000
Access Type : read
Access Addr : 00000000

Registers   : EAX=00000001 CS=001b EIP=00000000 EFLGS=00010246
            : EBX=0045FE84 SS=0023 ESP=03ABFF28 EBP=03ABFF60
            : ECX=00000000 DS=0023 ESI=03117460 FS=003b
            : EDX=000000FE ES=0023 EDI=03117468 GS=0000

Stack Trace : 004554D1 7C80B713 00000000 00000000
            : 00000000 00000000 00000000 00000000
            : 00000000 00000000 00000000 00000000
            : 00000000 00000000 00000000 00000000

Modules     :
          1 : 00400000 004F6000 c:\program files\interbank fx trader 4\terminal.exe
          2 : 035F0000 002C5000 c:\windows\system32\xpsp2res.dll
          3 : 10000000 0003D000 c:\data\unique345.dll
          4 : 5AD70000 00038000 c:\windows\system32\uxtheme.dll
          5 : 5FD00000 0000D000 c:\windows\system32\mfc42loc.dll
          6 : 605D0000 00009000 c:\windows\system32\mslbui.dll
          7 : 629C0000 00009000 c:\windows\system32\lpk.dll
          8 : 662B0000 00058000 c:\windows\system32\hnetcfg.dll
          9 : 71A50000 0003F000 c:\windows\system32\mswsock.dll
         10 : 71A90000 00008000 c:\windows\system32\wshtcpip.dll
         11 : 71AA0000 00008000 c:\windows\system32\ws2help.dll
         12 : 71AB0000 00017000 c:\windows\system32\ws2_32.dll
         13 : 72D10000 00008000 c:\windows\system32\msacm32.drv
         14 : 72D20000 00009000 c:\windows\system32\wdmaud.drv
         15 : 73DD0000 000FE000 c:\windows\system32\mfc42.dll
         16 : 74720000 0004C000 c:\windows\system32\msctf.dll
         17 : 74D90000 0006B000 c:\windows\system32\usp10.dll
         18 : 76380000 00005000 c:\windows\system32\msimg32.dll
         19 : 763B0000 00049000 c:\windows\system32\comdlg32.dll
         20 : 76B40000 0002D000 c:\windows\system32\winmm.dll
         21 : 76C30000 0002E000 c:\windows\system32\wintrust.dll
         22 : 76C90000 00028000 c:\windows\system32\imagehlp.dll
         23 : 76F20000 00027000 c:\windows\system32\dnsapi.dll
         24 : 76F60000 0002C000 c:\windows\system32\wldap32.dll
         25 : 76FB0000 00008000 c:\windows\system32\winrnr.dll
         26 : 76FC0000 00006000 c:\windows\system32\rasadhlp.dll
         27 : 77120000 0008B000 c:\windows\system32\oleaut32.dll
         28 : 773D0000 00103000 c:\windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.5512_x-ww_35d4ce83\comctl32.dll
         29 : 774E0000 0013D000 c:\windows\system32\ole32.dll
         30 : 77A80000 00095000 c:\windows\system32\crypt32.dll
         31 : 77B20000 00012000 c:\windows\system32\msasn1.dll
         32 : 77BD0000 00007000 c:\windows\system32\midimap.dll
         33 : 77BE0000 00015000 c:\windows\system32\msacm32.dll
         34 : 77C10000 00058000 c:\windows\system32\msvcrt.dll
         35 : 77DD0000 0009B000 c:\windows\system32\advapi32.dll
         36 : 77E70000 00092000 c:\windows\system32\rpcrt4.dll
         37 : 77F10000 00049000 c:\windows\system32\gdi32.dll
         38 : 77F60000 00076000 c:\windows\system32\shlwapi.dll
         39 : 77FE0000 00011000 c:\windows\system32\secur32.dll
         40 : 7C800000 000F6000 c:\windows\system32\kernel32.dll
         41 : 7C900000 000AF000 c:\windows\system32\ntdll.dll
         42 : 7C9C0000 00817000 c:\windows\system32\shell32.dll
         43 : 7E410000 00091000 c:\windows\system32\user32.dll

Call stack  :


I have created the DLL using C++ in Visual Studio 2003 on a Microsoft XP Professional system (SP3, 32bit). It has two functions unique345MyTestVoid() and unique345MyTestInt(). The DLL module contents are shown below.


// ======================================================
// The DLL
// ======================================================
#include "stdafx.h"

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    return TRUE;
}

extern "C" __declspec(dllexport) int __cdecl unique345MyTestVoid()         {  return 2; }
extern "C" __declspec(dllexport) int __cdecl unique345MyTestInt(int /*x*/) {  return 1; }

I created C++ program to verify that I can call LoadLibrary() and GetProcAddress() to correctly load and execute the functions. Everything works correctly.


When I create this simple MQL4 test script everything works:


//+------------------------------------------------------------------+
//|                                                        jdl02.mq4 |
//|                                                       Joe Linoff |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Joe Linoff"
#property link      ""

#import "C:\DATA\UNIQUE345.dll"
   int unique345MyTestVoid();
   int unique345MyTest(int);
#import

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   Print("unique345MyTestVoid() == ",unique345MyTestVoid()); // works!
   //Print("unique345MyTestInt(5) == ",unique345MyTestInt(5)); // crashes!
   datetime curr = TimeCurrent();
   Print("jdl02 - curr : ",curr," seconds since UTC");
//----
   return(0);
  }
//+------------------------------------------------------------------+

But when I uncomment the unique345MyTestInt(5) line it crashes.

//+------------------------------------------------------------------+
//|                                                        jdl02.mq4 |
//|                                                       Joe Linoff |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Joe Linoff"
#property link      ""

#import "C:\DATA\UNIQUE345.dll"
   int unique345MyTestVoid();
   int unique345MyTest(int);
#import

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   Print("unique345MyTestVoid() == ",unique345MyTestVoid()); // works!
   Print("unique345MyTestInt(5) == ",unique345MyTestInt(5)); // crashes!
   datetime curr = TimeCurrent();
   Print("jdl02 - curr : ",curr," seconds since UTC");
//----
   return(0);
  }
//+------------------------------------------------------------------+

This is extremely befuddling. Any help would be greatly appreciated.


Thanks,


Joe

 

I forgot to mention that the version of meta-trader that I am using is:


Interbank FX, LLC.

Version: 4.00 Build 220 (7 Nov 2008)

 
把你的函数贴出来。
 
extern "C" __declspec(dllexport) int __cdecl unique345MyTestVoid()         {  return 2; }
extern "C" __declspec(dllexport) int __cdecl unique345MyTestInt(int /*x*/) {  return 1; }

will be more correct


extern "C" __declspec(dllexport) int __stdcall unique345MyTestVoid()         {  return 2; }
extern "C" __declspec(dllexport) int __stdcall unique345MyTestInt(int /*x*/) {  return 1; }
 
mql_coder:

will be more correct



Thanks mql_coder.


I have tried the __stdcall protocol and it worked but but then I have to call the function using the name: "_<func>@<size>" so "unique345MyTestInit" becomes "_unique345MyTestInit@4" which is kind of unwieldy. This is what it looks like in the MQL4 code:


// Using the __stdcall protocol

#import "C:\DATA\UNIQUE345.dll"
   int _unique345MyTestInt@4(int);
#import

print("contents = ",_unique345MyTestInt@4(10));


As I mentioned earlier, it works just fine but it looks rather strange and I still can't figure out why the crash would occur for "__cdecl".


I would be very happy if I could just call it using the "unique345MyTestInt" rather than the "_unique345MyTestInt@4" name but can live with this for now.


Do you know of other folks that have used Visual Studio 2003 to create DLLs for MQL4? Do I need to use a newer version?

 
Figured it out. I had setup my Visual Studio project incorrectly so it was not picking up the DEF file properly. Everything works fine now.
 
jlinoff:
Figured it out. I had setup my Visual Studio project incorrectly so it was not picking up the DEF file properly. Everything works fine now.

Hello,

I have the same problem. I must call the function "_<func>@<size>". Can you say me please, how you solve the problem?

Thx

 
daggz:

Hello,

I have the same problem. I must call the function "_<func>@<size>". Can you say me please, how you solve the problem?

This is a question that should be answered by the user manual of your compiler. There almost certainly is a way to declare under which name a function should be exported. Some compilers for example seem to need this to be declared in a separate .def file. Read the manual of your compiler.

Reason: