DLL Matlab Interfacing issues

 

Hi

I have written a DLL to interface with matlab code. The Dll has a function to start matlab engine and then call several functions. The Matlab code is part of an EA. Matlab engine gets initiliazed in the init() function of the EA and is supposed to close on the deinit() function. However, I found that the Matlab engine closes as soon as init() completes, so I can no longer call it from start(). Upon some investigation I found that the DLL Thread_Detach in the DLLMain() function is being called more times than the DLL Thread_Attach. The larger number of thread detaches reduces the reference count of the dll to 0 hence causing a FreeLibrary being called (internally from MetaTrader or by Windows itself). The unload library message received by the DLL goes further to the Matlab engine (since it is in turn loaded by my DLL), causing it to close. Reason I think this happens is that by design, Windows System calls the DllMain each time a thread is created by MT4 with the message Thread_Attach. This happens for every Dll currently loaded by MT4. When the threads get terminated, a Thread_Detach message is sent to all attached DLLs. Now, when I suppose the thread in which init() function executes terminates, it takes along Matlab engine with it. This also happens even if Matlab is started from the start() function. This issue does not crop up when running it from a script presumably because the init(), start() and deinit() for a script run in the same thread so the DLL wouldn't be unloaded prematurely.

One workaround is to start matlab engine on every start() tick, but it is a little time consuming process taking a few seconds and I want to avoid it. Any suggestions?


SandsofTime

 
msafri:

Hi

One workaround is to start matlab engine on every start() tick, but it is a little time consuming process taking a few seconds and I want to avoid it. Any suggestions?

SandsofTime

This is a bit late ... maybe use scripts to start and stop Matlab engine rather than the EA?
 

msafri:

When the threads get terminated, a Thread_Detach message is sent to all attached DLLs. Now, when I suppose the thread in which init() function executes terminates, it takes along Matlab engine with it.

You are doing the wrong things in your DLLMain(). If you don't have anything to do in DLL_Thread_Detach then simply ignore this event.

 

Just a few hints:

  1. never ever start anything from DLLMain, this is generally not a good idea. Try to google something about dll loading...
  2. MT4 behaves differently in testing and in trading
    • In testing, the simulation runs in one thread only. When you click start button in tester tool, MT attaches DLL to it's thread, executes init, start for each tick and deinit. Then MT detaches DLL thread. This is possible, because no parallel processing could occur, start function is called for each tick in sequence, no parallel processing.
    • In trading mode, multiple MT threads are employed. The reason is simple - if one tick is received just after another tick, and the first one is still processing, the second one shouldn't be delayed in processing. The consequence is that also Matlab could be called multiple times in parallel, if you call it directly from your method in DLL.
  3. In trading mode, thread attaches DLL, calls init and then detaches DLL. The consequence is that Matlab engine stops just after the init function had finished.
  4. If you start Matlab engine from one thread, you can't access it from another thread.

All mentioned above means, that the only correct way for running Matlab engine from MT in trading mode, is running it in a separate thread. Multithreaded DLL requires synchronization between threads, using synchronization object like mutex or semaphore. Almost any mistake in synchronization causes MT crash, or even worse things with older operating system. That is really critical when you have your trades open, be careful and test, test, test:-)

 
schedek:

Just a few hints:

  1. never ever start anything from DLLMain, this is generally not a good idea. Try to google something about dll loading...
  2. MT4 behaves differently in testing and in trading
    • In testing, the simulation runs in one thread only. When you click start button in tester tool, MT attaches DLL to it's thread, executes init, start for each tick and deinit. Then MT detaches DLL thread. This is possible, because no parallel processing could occur, start function is called for each tick in sequence, no parallel processing.
    • In trading mode, multiple MT threads are employed. The reason is simple - if one tick is received just after another tick, and the first one is still processing, the second one shouldn't be delayed in processing. The consequence is that also Matlab could be called multiple times in parallel, if you call it directly from your method in DLL.
  3. In trading mode, thread attaches DLL, calls init and then detaches DLL. The consequence is that Matlab engine stops just after the init function had finished.
  4. If you start Matlab engine from one thread, you can't access it from another thread.

All mentioned above means, that the only correct way for running Matlab engine from MT in trading mode, is running it in a separate thread. Multithreaded DLL requires synchronization between threads, using synchronization object like mutex or semaphore. Almost any mistake in synchronization causes MT crash, or even worse things with older operating system. That is really critical when you have your trades open, be careful and test, test, test:-)

 

Is it not possible just to start MATLAB once at 1st tick at start than set a variable flag that is started ??? Than at following ticks just access it ??

 
fajst_k:

Is it not possible just to start MATLAB once at 1st tick at start than set a variable flag that is started ??? Than at following ticks just access it ??

No, that's really not possible, because MATLAB terminates just after the processing of first tick finishes. Imagine a situation, that your MATLAB engine is still starting and another tick starts it or just tries to access it. As the processing of ticks is multithreaded, accessing MATLAB always requires synchronization. And MQL doesn't support synchronization, so you have to do this inside the DLL.
Reason: