I'm starting a FireMonkey application in Delphi XE7 that must call some DLL's which have themselves forms (also created in Delphi XE7).
I load the DLL and call my exported procedure (no parameters), and the form loads and works as expected (ShowModal). I close that form and the main application resumes and works perfectly, until the moment the user terminates the application and the FreeLibrary is called. An Access Violation is then raised with the following message:
"First chance exception at $045B30E6. Exception class $C0000005 with message 'access violation at 0x045b30e6: read of address 0x00000008'. Process bpltesteVCL.exe (6708)"
I ran some tests with a basic test application and found out it only happens if the DLL has a FireMonkey TForm - VCL runs fine.
These are the combinations I tried in my testings with virtually the same code: VCL App/VCL Dll = OK; VCL App/FMX Dll = Fail; FMX App/FMX Dll = Fail; FMX App/VCL Dll = OK. These were only for testing purposes, since my goal is a full FMX application.
The code I used to load the library:
procedure TForm2.Button1Click(Sender: TObject);
type
TFExecute = procedure; StdCall;
var
Execute: TFExecute;
Ext: HMODULE;
begin
Ext := LoadLibrary(PChar(ExtractFilePath(ParamStr(0)) + 'dlltest.dll'));
if Ext <> 0 then
begin
try
@Execute := GetProcAddress(Ext, 'Execute');
if Assigned(Execute) then
Execute
else
ShowMessage('Function not found !');
finally
FreeLibrary(Ext);
end;
end
else
ShowMessage('DLL not found');
end;
And the Dll code for 'Execute':
procedure Execute; StdCall;
begin
fMain := TfMain.Create(nil);
fMain.ShowModal;
fMain.Free;
end;
Exports
Execute;
The DLL form has no component inside. Only the plain form. Also, no units were added to it that were not needed to load the form itself.
I have been searching and found some similar cases, and the problem seems to be the GDI+ initialization and finalization, but unfortunately, the answers there don't work for me:
FMX form in a DLL (firemonkey/delphi)
This couldn't help me, because in this method the dll is loaded in the initialization section of a unit, making it in fact similar to static loading, which I cannot use. Still I tried it for the sake of testing, and it crashed with an Access Violation in the same maner.
FireMonkey Form in a dll, loaded from a VCL Application
This was in fact the closest I got to a solution to my problem, but unfortunately, the solution given here seems to work for XE2, but not for later versions of Delphi, because one of the most important methods used here is GetMeasureBitmap, which only exists (by that name at least) in XE2.
I did search for an equivalent in XE7 so I could find the solution before posting the question, but couln't get anything of the sort.
Is there any way to load FMX forms in a dll in Delphi XE7?
EDIT: Continuing the research for a solution, I tried the following:
- All the mentioned combinations with BPL instead of DLL
- Usage of ShareMem / FastShareMem
No change on the mentioned behaviour!