Please bear in mind I was clutching at straws through lack of info trying to think why your DLL was still crashing anyway ....
Yes Correct. So your DLL should take some responsibility for what its doing incase of crashes / Bad usage by the calling app / Unreliable calling language (MQL4) / Or to ease the usage of the calling App.
If the DLL is being Unloaded and some of your Deinit()'s havent been executed then as you say theses objects wont be freed so ...
Its been my experience (non documented feature!) - and common sense would back this up - that :
Both the Init() and DeInit() functions in an EA are executed within the Main MT4 Apps Thread. So Your Init / DeInit implementation need not be thread safe. Only the Start() Function is executed by in another thread.
As long as you dont call Init() or DeInit() from within your MT4 Start() Function All will be OK, and you can use a simple Tlist for the purpose.
This is slightly overkill but good practice none the less. If nothing else doing it reminds you to think about cleaning up. So with the above in mind you could do something like :
DislikedThe way I have it written, if deinit() does not get called, the object will not get freed. But aside from the memory leak that shouldn't cause crashing because the second object will have a new memory location, correct?Ignored
If the DLL is being Unloaded and some of your Deinit()'s havent been executed then as you say theses objects wont be freed so ...
Its been my experience (non documented feature!) - and common sense would back this up - that :
Both the Init() and DeInit() functions in an EA are executed within the Main MT4 Apps Thread. So Your Init / DeInit implementation need not be thread safe. Only the Start() Function is executed by in another thread.
As long as you dont call Init() or DeInit() from within your MT4 Start() Function All will be OK, and you can use a simple Tlist for the purpose.
This is slightly overkill but good practice none the less. If nothing else doing it reminds you to think about cleaning up. So with the above in mind you could do something like :
Inserted Code
library YourDLL; uses SysUtils,Classes; type tyourobject = class(tobject) private name : string; end; var SaveExit: Pointer; objs : tlist; function YourNormal_InitObj(pairname : pchar) : longint; stdcall; var tmpobj : tyourobject; begin tmpobj := tyourobject.create; objs.Add(tmpobj); tmpobj.name := string(pairname); // do other init stuff result := longint(tmpobj); end; function YourNormal_DEInitObj(objptr : longint) : longint; stdcall; begin objs.remove(pointer(objptr)); tyourobject(objptr).free; result := 0; end; procedure LibExit; begin try while objs.Count >0 do begin ///edited tyourobject(objs[0]).free; objs.delete(0); ///edited end; ///edited objs.Free; finally ExitProc := SaveExit; // restore exit procedure chain end; end; exports YourNormal_InitObj index 1, YourNormal_DEInitObj index 2; begin SaveExit := ExitProc; // save exit procedure chain ExitProc := @LibExit; // install LibExit exit procedure objs := tlist.create; end.