用Delphi XE7 FireMonkey FMX Form调用DLL后,在FreeLibrary上访问冲突,可能是GDI +初始化/终结问题

时间:2015-02-23 23:37:48

标签: delphi dll gdi+ firemonkey access-violation

我正在Delphi XE7中启动一个FireMonkey应用程序,该应用程序必须调用一些具有自身形式的DLL(也是在Delphi XE7中创建的)。

我加载DLL并调用我的导出过程(无参数),表单加载并按预期工作(ShowModal)。我关闭该表单,主应用程序恢复并完美运行,直到用户终止应用程序并调用FreeLibrary。 然后引发访问冲突,并显示以下消息:

  

“$ 045B30E6的第一次机会异常。异常类$ C0000005,消息'访问冲突位于0x045b30e6:读取地址0x00000008'。处理bpltesteVCL.exe(6708)”

我使用基本测试应用程序运行了一些测试,发现只有DLL具有FireMonkey TForm才会发生 - VCL运行正常。

这些是我在测试中尝试使用几乎相同代码的组合: VCL App / VCL Dll = OK; VCL App / FMX Dll =失败; FMX App / FMX Dll =失败; FMX App / VCL Dll = OK。 这些仅用于测试目的,因为我的目标是完整的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代码:

procedure Execute; StdCall;
begin
     fMain := TfMain.Create(nil);
     fMain.ShowModal;
     fMain.Free;
end;

Exports
       Execute;

DLL表单里面没有组件。只有普通的形式。此外,没有添加任何单元,不需要加载表单本身。

我一直在搜索并找到一些类似的案例,问题似乎是GDI +初始化和最终确定,但不幸的是,那里的答案对我不起作用:

FMX form in a DLL (firemonkey/delphi)

这对我没有帮助,因为在这个方法中,dll被加载到一个单元的初始化部分,使其实际上类似于静态加载,我无法使用。我仍然为了测试而尝试了它,并且它在同一个方面遭到了访问冲突的破坏。

FireMonkey Form in a dll, loaded from a VCL Application

这实际上是我最接近我的问题的解决方案,但不幸的是,这里给出的解决方案似乎适用于XE2,但不适用于更高版本的Delphi,因为这里使用的最重要的方法之一是GetMeasureBitmap ,仅在XE2中存在(至少以该名称)。

我确实在XE7中搜索了一个等价物,所以我可以在发布问题之前找到解决方案,但是不能得到任何类似的东西。

有没有办法在Delphi XE7中的dll中加载FMX表单?

编辑: 继续研究解决方案,我尝试了以下方法:

  • 所有提到的与BPL而不是DLL的组合
  • 使用ShareMem / FastShareMem

上述行为没有变化!

0 个答案:

没有答案