使用Delphi XE7 FireMonkey FMX表单调用DLL后,在FreeLibrary上发生访问冲突,可能是GDI+;初始化/定稿问题

使用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’。处

我正在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应用程序

我用于加载库的代码:

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;