我有一个DLL和一个程序,都是用Delphi 2007编写的。程序传递了一个接口,该接口从IInterface下载并且没有GUID(因此没有COM)到DLL存储它供以后使用。
这似乎工作正常,但有时我会在程序关闭并卸载DLL时遇到访问冲突。我不确定这些AV的原因。有可能接口超出范围并通过引用计数驻留在程序上下文中的底层对象被释放,从而导致内存损坏,因为涉及两个不同的内存管理器。
我没有使用sharemem,我不希望出于各种原因(其中一个原因是其他程序没有用Delphi编写可能想要使用该DLL)。
我知道我不应该以这种方式传递字符串,打开数组和对象,但界面是否有效?
答案 0 :(得分:2)
是的,如果全部是德尔福,这应该可以正常工作。如果接口发生变化,您必须确保编译两者。 C ++编译器似乎兼容,但要注意其他编译器。
通常,引用计数达到零会导致对象的创建者释放它。那里的不同内存管理员没有问题。
可能的问题是你的dll仍然通过接口引用了一个对象,并调用IUnknown.Release来降低引用计数,当它不再需要它时。如果由于某种原因引用的对象已经被释放,你将获得AV。确保在关闭应用程序之前删除通过引用对象的所有引用(仔细检查全局变量)。
FastMM的调试选项可以帮助您找到问题。
答案 1 :(得分:0)
向DLL传递接口和从DLL传递接口没有任何问题。毕竟,这正是您每次使用Windows API界面时所做的事情。因此,你的问题更深层次。
缺少GUID是一个很难解决的问题。只需按Ctrl + Shift + G.然后你没有使用COM的障碍。当您的接口具有GUID时,即使您不使用COM,Delphi中与接口相关的所有内容也会变得更加容易。
如果您的DLL是COM DLL,那么主机程序将能够检查是否可以安全地卸载DLL。 Delphi的COM框架自动跟踪该DLL中是否还有活动的对象。当主机希望卸载DLL时,它会询问DLL是否安全。
您的对象应该是COM对象。宿主程序将使用对象的GUID,使用OS标准CoCreateInstance
函数创建对象的实例。您的DLL已经在操作系统中注册,因此CoCreateInstance
将知道自动加载DLL并调用其中的正确函数来实例化您的类。 (如果您也在编写主机,那么只需使用Delphi的CreateComObject
函数。)