我试图找出这个问题。使用boost :: signals2和卸载DLL时访问冲突
假设您的代码使用boost::signals2
进行对象之间的通信。让我们称他们为“色彩”。这些colorscales的代码通常位于与使用它们的代码相同的DLL中。我们称之为main.dll
但是有时来自其他DLL的代码需要使用这些对象,这就是问题开始的地方。
基本上,应用程序是相当大的,大多数的DLL被加载做一些工作,然后他们被卸载。对于包含colorscales代码的DLL,情况并非如此,它在应用程序正常运行时期间被卸载。因此,当其中一个DLL被加载(我们称之为tools.dll
)并且一些代码运行时,它可能想要使用这些色彩对象并与它们通信,因此我连接到这些对象提供的信号。
的问题是,boost
是非常懒惰,所有的聪明,当你disconnect()
插槽,它实际上并没有抹去connection
和与它(如boost::bind
对象,例如)相关的东西。它只是设置一个标志,这个connection
现在已断开连接,并在稍后清理它(实际上,当您连接新插槽时清除其中的2个对象,当您调用1.57版本时调用其中的1个对象)。你可能已经看到了这将会到来。
所以,当你不需要更多的工具时,你断开这些信号,然后卸载应用程序tools.dll
。
然后在稍后的阶段,一些代码从main.dll
执行,导致一个色彩信号被调用。 boost::signals2
去调用它,但在它试图清理一个断开的插槽之前。这是发生访问违规的地方,因为内部连接有一个shared_state对象或类似的东西,它试图以线程安全的方式清理自己。但它面临的问题是,它试图调用的代码已经不存在,因为DLL被卸载,所以引发了Access Violation异常。
我试图通过在卸载DLL之前调用带有一些虚拟参数的信号来解决这个问题,并且通过连接然后断开更多的插槽来解决这个问题(这是一个愚蠢的想法,因为它不能解决问题,它)一些预定义的时间量(比所有时隙多2或3倍)。
它的工作,或我认为是这样,因为它现在不会立即崩溃,而是在下次加载相同的tools.dll
时崩溃。我仍然需要弄清楚它在哪里以及为什么会崩溃,但它在boost
之内的其他地方。
所以,我想问一下,我有哪些修复方法? 我的想法是
- 实现我自己的连接,在一个更简单的方式
- 提供了一个更简单的方法来沟通一样,回调的作品,例如
- 找到一个解决方法
boost
如此懒惰和聪明。
你有没有想过不通过DLL传递提升对象?重新发明whell(子弹一)是一个坏主意。找到解决方法将帮助您了解更多信息,但可能需要无限期的时间。我会去更简单的方法。 – UmNyobe 2015-02-24 18:57:14
那么,这是问题的全部。这是因为它没有解决方法就无法工作。问题是:我应该选择哪种解决方法 – Spo1ler 2015-02-24 23:10:11