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.