InnoSetup和Delphi DLL之间的内存管理问题

时间:2014-02-04 09:07:18

标签: delphi memory-management dll themes inno-setup

情况:

  • 一个DLL:

    • 使用Delphi XE3 32bit
    • 编写和编译
    • 导出一个显示模态VCL格式的函数:
      function EditOptions(AIniFileName: PAnsiChar; ALCID: Integer): Boolean; stdcall;

    • 也是一个COM服务器

  • 使用InnoSetup 5.5.4创建的安装程序:
    • 通过external 'EditOptions@files:mydll.dll stdcall' - 指令导入所述DLL函数,并在需要时调用它
    • 在通过Inno实用程序函数UnloadDLL
    • 注册COM服务器之前显式卸载DLL

问题:

  • 当...
    • Windows使用的是Classic以外的主题
    • 安装期间显示DLL中的模式对话框
  • 安装程序在卸载DLL时挂起
  • 没有显示错误消息
  • 日志表示没有运行时异常

请注意,为了保持这个简短,我故意省略了一些更特殊细节的解释,例如:为什么我明确地卸载DLL或为什么COM服务器需要自定义导出。如果您认为这些细节是相关的并且应该添加,请告诉我。

为了进一步分析这个,我创建了一个调用DLL函数的虚拟主机EXE,这样我就可以更轻松地在调试器中运行整个事情了。这样做会导致在调用TUxThemeStyle.UnloadThemeData的行CloseThemeData()中引发AV。当断点直接放在该行并从停止处向前走时,我实际上最终会得到“太多连续异常”错误。我只能在为主机EXE启用运行时主题时重现错误。

回顾我们的git历史,自从我们从Delphi 2010切换到XE3之后,这个问题似乎一直存在(不幸的是,安装程序不是我们常规测试套件的一部分,所以现在只有在实际版本的工作中才出现这个问题关闭,因为DLL导出专门为安装程序的利益而存在。)

任何可能导致此问题的想法?这真的可能与主题相关(我在这个项目中没有与主题相关的自定义代码)或者这可能只是内存损坏的一个症状造成了其他地方吗?例如。我曾经有一个错误,在之前的主题拆解代码中以AV的形式出现,但在这种情况下,它实际上是由于initialization部分的匿名方法引用泄露...

更新:我努力尝试制作一个愚蠢的示例项目来单独展示问题,但到目前为止没有运气。不过,我已经设法缩小了一些范围。首先,这里有一些关于代码的更多事实:

  • 我正在展示的对话是TForm的三度后代。祖先完成了几件事:
    • TAppModalDialog实现了一个特殊的构造函数CreateOnTop,确保它显示为当前进程中最顶层的窗口(该项目是一个插件,加载到多窗口的第三方主机中,但不幸的是不通信他们的窗口句柄用作模态父项) - 它通过操纵全局Application.Handle来实现这一点。
    • TTabbedDialog是基于接口的框架的一部分,允许通过工厂模式注册“页面”(实际上是TFrame - 后代) - 在运行时,表单将动态创建TTabSheet s在TPageControl中并实例化并将已注册的页面框架添加到它们

我已经用虚拟替换了对实际对话框的调用,逐渐使用继承链从空白TForm到我的TAppModalDialog,最终到我的TTabbedDialog类。问题才开始发生在最后一级。我还注释了项目周围的所有页面注册,以便对话框出现一个空的页面控件(这会排除任何页面中的代码作为问题的原因)。然后,我在TTabbedDialog类本身的例程中注释掉了所有代码和数据成员,只留下空方法体来满足接口实现要求和TPageControl组件(以及两个空TImageList } s和TBalloonHint组件) - >错误仍然存​​在。

然后我将对虚拟对话框的调用复制到一个新的DLL项目中,除了这个和标签对话框架之外别无其他。如果我将该DLL加载到我的虚拟主机EXE中,则问题会再次出现 ... 叹息

所以,我的怀疑仍然是某些地方必然存在某种内存损坏,我看到的错误只是其中的一个症状。所以真正的问题是我怎么能最终得到这个呢?

我现在继续注释/删除生产DLL中的位...

0 个答案:

没有答案
相关问题