使用Delphi XE7 FireMonkey FMX表单调用DLL后,在FreeLibrary上发生访问冲突,可能是GDI+;初始化/定稿问题
我正在Delphi XE7中启动一个FireMonkey应用程序,该应用程序必须调用一些具有表单的DLL(也在Delphi XE7中创建) 我加载DLL并调用导出的过程(无参数),表单按预期加载并工作(ShowModal)。我关闭该表单,主应用程序就会恢复并正常工作,直到用户终止应用程序并调用FreeLibrary为止。 然后,通过以下消息引发访问冲突: “第一次机会$045B30E6发生异常。异常类别$C0000005,消息为‘0x045b30e6的访问冲突:读取地址0x00000008’。处理bpltesteVCL.exe(6708)” 我用一个基本的测试应用程序运行了一些测试,发现只有当DLL有FireMonkey TForm-VCL运行正常时才会发生这种情况 以下是我在测试中用几乎相同的代码尝试的组合: VCL应用程序/VCL Dll=正常;VCL应用程序/FMX Dll=失败;FMX应用程序/FMX Dll=失败;FMX应用程序/VCL Dll=正常。 这些只是出于测试目的,因为我的目标是一个完整的FMX应用程序 我用于加载库的代码:使用Delphi XE7 FireMonkey FMX表单调用DLL后,在FreeLibrary上发生访问冲突,可能是GDI+;初始化/定稿问题,delphi,dll,gdi+,firemonkey,access-violation,Delphi,Dll,Gdi+,Firemonkey,Access Violation,我正在Delphi XE7中启动一个FireMonkey应用程序,该应用程序必须调用一些具有表单的DLL(也在Delphi XE7中创建) 我加载DLL并调用导出的过程(无参数),表单按预期加载并工作(ShowModal)。我关闭该表单,主应用程序就会恢复并正常工作,直到用户终止应用程序并调用FreeLibrary为止。 然后,通过以下消息引发访问冲突: “第一次机会$045B30E6发生异常。异常类别$C0000005,消息为‘0x045b30e6的访问冲突:读取地址0x00000008’。处
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;
DLL窗体内部没有组件。只有简单的形式。此外,没有向其中添加加载表单本身不需要的单元
我一直在搜索并发现一些类似的案例,问题似乎是GDI+的初始化和终结,但不幸的是,那里的答案对我来说并不适用:
这对我没有帮助,因为在这种方法中,dll加载在单元的初始化部分,使它实际上类似于静态加载,而我不能使用静态加载。不过,为了测试,我还是试了一下,结果在同一个人身上发生了访问冲突
事实上,这是我找到的最接近问题解决方案,但不幸的是,这里给出的解决方案似乎适用于XE2,但不适用于更高版本的Delphi,因为这里使用的最重要的方法之一是GetMeasureBitmap,它只存在于XE2中(至少用这个名称)
我确实在XE7中搜索了一个等价物,以便在发布问题之前找到解决方案,但没有得到类似的结果
在Delphi XE7中有没有办法在dll中加载FMX表单
编辑:
继续研究解决方案,我尝试了以下方法:
- 所有提到的组合都使用BPL而不是DLL
- ShareMem/FastShareMem的使用
上述行为没有改变 有两个FMX实例。可能是太多了。您需要使用DLL吗?如果是,为什么?嗨,大卫。我需要dll的,因为这是一个插件系统,类似于,但这次在一个FMX应用程序。我确实用BPL试过了,但问题是一样的。即使主应用程序在VCL中,dll/bpl在FMX中(因此,每个应用程序只有一个实例),它仍然会失败。我可以在VCL中使用插件,但这会限制我在支持的平台方面的选择,因此我正在寻找FMX解决方案。看起来框架设计根本不支持这种用法。你认为框架本身可能有缺陷吗?如果不是缺陷,那只是设计选择的结果。我没有你走得那么远。当我关闭模态窗体时,主机的主窗体变得没有响应。
procedure Execute; StdCall;
begin
fMain := TfMain.Create(nil);
fMain.ShowModal;
fMain.Free;
end;
Exports
Execute;