【问题标题】:Can I pass an interface (IInterface) to a DLL?我可以将接口 (IInterface) 传递给 DLL 吗?
【发布时间】:2010-08-06 07:16:51
【问题描述】:

我有一个 DLL 和一个程序,它们都是用 Delphi 2007 编写的。程序将一个接口传递给 DLL,该接口源自 IInterface 并且没有 GUID(所以这里没有 COM)到 DLL 存储它以供以后使用。

这似乎工作正常,但有时我会在程序关闭并卸载 DLL 时遇到访问冲突。我不确定这些 AV 的原因。接口可能超出范围,通过引用计数,驻留在程序上下文中的底层对象被释放,从而导致内存损坏,因为涉及到两个不同的内存管理器。

我没有使用 sharemem,并且出于各种原因我不想使用(其中一个原因是其他不是用 Delphi 编写的程序可能想要使用该 DLL)。

我知道我不应该以这种方式传递字符串、打开数组和对象,但是接口应该工作吗?

【问题讨论】:

    标签: delphi delphi-2007


    【解决方案1】:

    是的,如果都是 Delphi,那应该可以正常工作。如果界面发生变化,您必须确保编译两者。 C++ 编译器似乎兼容,但请注意其他编译器。

    通常引用计数达到零会导致对象的创建者释放它。那里的不同内存管理器没有问题。

    问题可能是您的 dll 仍然通过接口引用对象,并在不再需要时调用 IUnknown.Release 以降低引用计数。如果由于某种原因引用的对象已被释放,您将获得 AV。确保在关闭应用程序之前删除通过引用对对象的所有引用(仔细检查全局变量)。

    FastMM 的调试选项可能会帮助您找到问题。

    【讨论】:

      【解决方案2】:

      在 DLL 之间传递接口并没有错。毕竟,这正是您每次使用 Windows API 接口时所做的事情。因此,您的问题更深层次。

      缺少 GUID 是一个很容易解决的问题。只需按 Ctrl+Shift+G。那么你就没有使用 COM 的障碍了。当你的接口有 GUID 时,Delphi 中所有与接口相关的东西都会变得更容易,即使你没有使用 COM。

      如果您的 DLL 是 COM DLL,那么主机程序将能够检查卸载 DLL 是否安全。 Delphi 的 COM 框架会自动跟踪该 DLL 中是否仍有对象处于活动状态。当主机希望卸载 DLL 时,它会询问 DLL 这样做是否安全。

      您的对象应该是一个 COM 对象。主机程序将使用您的对象的 GUID 使用 OS 标准 CoCreateInstance 函数创建您的对象的实例。您的 DLL 将在操作系统中注册,因此CoCreateInstance 将知道自动加载您的 DLL 并在其中调用正确的函数来实例化您的类。 (如果你也在编写主机,那么只需使用 Delphi 的 CreateComObject 函数。)

      【讨论】:

      • 对不起,我的意思是写 GUID 而不是 GUI。当然,没有 GUI 并不能阻止我使用 COM,但是没有 GUID 的接口可以。
      • 啊,这更有意义。我已经相应地更新了我的答案。
      猜你喜欢
      • 2011-07-17
      • 2015-02-09
      • 2018-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多