0

I have a native library built with Visual Studio 2012. Required project configuration properties:

  • General / Platform Toolset = Visual Studio 2012 - Windows XP (v110_xp)
  • C/C++ / Code Generation / Runtime Library = Multi-threaded (/MT)

ExpertSample.cpp:

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mutex>

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

#define MT4_EXPFUNC __declspec(dllexport)
static std::mutex mutex;

MT4_EXPFUNC void __stdcall libInit() {
    std::lock_guard<std::mutex> guard(mutex);
    OutputDebugStringA("libInit");
}
MT4_EXPFUNC void __stdcall libDeInit() {
    std::lock_guard<std::mutex> guard(mutex);
    OutputDebugStringA("libDeInit");
}

ExpertSampleTest.mq4:

#import "ExpertSample.dll"
void libInit();
void libDeInit();
#import

int init() {
    libInit();
    return(0);
}
int deinit() {
    libDeInit();
    return(0);
}
int start() {
//    libDeInit();
    return(0);
}

Testing it on Windows 7 (x64) with MetaTrader build 451 (also for build 438) works normally.

Testing it in the WinXP Mode Virtual PC (running inside the same Windows 7), when the EA is removed from the chart, the whole terminal is closed. There is no crash report dialog, or anything in the log files.

  • If I call libDeInit() from start() it works fine.
  • If I remove the lock guard from libDeInit(), it works fine.

The above code is just a subset of a larger project. In that project, when the library was built with all kind of debug information and a lot of outputs, the problem seemed to happen less often.

Does anybody know how to fix it, or whether it's a MetaTrader 4 or WinXP Mode Virtual PC issue?

Ogmios
  • 646
  • 7
  • 12

1 Answers1

0

The C++ code itself looks good. Possible issues I see:

  • If the DLL is loaded but the constructor for the mutex is not called, that would explain your problem. That would be a problem in the environment loading the DLL.
  • Check the calling convention. Is it stdcall or cdecl? Using the wrong one can cause all kinds of issues, maybe even no issues under some circumstances.
  • Try replacing the mutex with a function returning a reference to a mutex, which is placed as function-static instance inside that function. If that helps, I'd say that it proves that the constructor is not called.
  • You don't need DllMain(), I'd only use it to call DisableThreadLibraryCalls().
Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55