DLL内存pipe理器混合

我写了一个应用程序,允许人们贡献插件来扩展function。 这样的插件被部署为DLL文件,框架可以在运行时select。 每个插件都具有一个工厂函数,在应用程序的生命周期中多次调用该工厂函数来创build对象。 到目前为止,为了处理这些对象的所有权问题,我在返回的对象上使用了一个简单的计数共享指针,以便在最后一个引用被删除时被销毁。

然而,这往往会在Windows上触发崩溃,因为在插件DLL中新对象不是不太可能发生的,但是后来(由于在共享指针上调用了deref()调用)在主应用程序中被删除,并AFAIK this malloc / free mixup在Windows上是不可以的。

我目前的解决办法是让deref()不要调用'delete this'。 直接而是一个'释放();' 必须由插件实现的function,并调用“删除这个”。 然而,每个插件都必须实现这个微不足道的function是非常令人讨厌的 – 我为此提供了一个方便的macros插件作者必须使用的工作。 有人可能有其他的想法吗?

到目前为止,我的方法是所有由插件贡献的对象都被分配到插件中,并在那里被释放 – 当然,另一种方法是让所有内存在主应用程序中分配(通过提供一个类似malloc的函数的指针到他们可以根据需要调用的插件),并在那里发布。 这个问题是对插件作者来说不是那么方便,我想。

我对这个问题有任何其他观点感兴趣。

更新:我刚刚意识到,我可以重新实现运算符new和运算符删除插件返回的对象的基类,以便new'ing它们并删除它们将始终导致函数调用到同一模块(以便所有分配和免费都在插件或框架中完成)。

Solutions Collecting From Web of "DLL内存pipe理器混合"

有两个解决方案。 解决方案之一是“共享更多” – 如果双方使用相同的CRT DLL(MSVC中的/ MD或/ MDd),则可以跨越DLL边界移动新的/删除。 解决方案二是“共享少” – 让每个DLL有它自己的C ++堆,不跨越DLL边界拆分新/删除。

事实证明,确保内存不被分配在一个DLL中并在另一个DLL中释放的最简单的方法是:对从插件返回的对象的基类重新实现operator newoperator delete 。 在这些函数的实现中,调用“alloc”和“free”函数(在加载插件时已经从主应用程序传递过来)。 这样,插件可以继续使用“新建”和“删除”,但内存将实际分配和释放在主应用程序。

如果DLL代码负责分配对象,它也应该负责释放它们。 我认为你的问题是更多的引用计数和“删除这个”。 如果你想走这条路,为什么不简单地把对象作为COM对象来实现呢? 这毕竟是COM设计要解决的主要问题之一!