C++ 让两个DLL共享一个静态库有什么陷阱?

C++ 让两个DLL共享一个静态库有什么陷阱?,c++,windows,dll,C++,Windows,Dll,假设你有两个DLL 动态链接库A和动态链接库B 它们都静态链接到一个静态库(即.lib文件)。我们称那个图书馆为L 我知道L完全链接到A和B,分别有效地创建了LA和LB。然而,当来自LA的对象O从A传递到B时会发生什么?我假设在LA中执行代码,而在B中执行LB代码,因为链接就是这样发生的。如果在A中创建O,卸载A,然后在B中使用O,会发生什么不好的事情 静态库只是对象文件的集合。当您链接到静态库时,一切都会发生,就好像静态库的代码已经包含在您的库中一样 因此,如果静态库中存在全局变量,则每个DL

假设你有两个DLL

动态链接库A和动态链接库B

它们都静态链接到一个静态库(即.lib文件)。我们称那个图书馆为L


我知道L完全链接到A和B,分别有效地创建了LA和LB。然而,当来自LA的对象O从A传递到B时会发生什么?我假设在LA中执行代码,而在B中执行LB代码,因为链接就是这样发生的。如果在A中创建O,卸载A,然后在B中使用O,会发生什么不好的事情

静态库只是对象文件的集合。当您链接到静态库时,一切都会发生,就好像静态库的代码已经包含在您的库中一样


因此,如果静态库中存在全局变量,则每个DLL将获得自己的副本,这可能是您想要的,也可能不是您想要的。

静态库只是对象文件的集合。当您链接到静态库时,一切都会发生,就好像静态库的代码已经包含在您的库中一样

因此,如果静态库中有全局变量,每个DLL将获得自己的副本,这可能是您想要的,也可能不是您想要的

然而,当来自LA的对象O从A传递到B时会发生什么

它实际上取决于对象
O
是什么,以及库
L
对它做了什么。如果
O
是一个完全依赖于存储在该对象中的状态的对象,那么一切都可能正常。但是,如果
O
不是,如果
O
依赖于全局状态或其他对象或某物的状态,则可能会出现问题

避免问题的最好方法是在两个DLL之间有适当的绝缘层。也就是说,你根本不应该在两者之间传递
O
,因为它们谈论的不是同一个
O
。一般来说,如果<代码> L>代码>大到足以要求你在两个用户之间传递它的对象,那么它就足够大了,你可能应该考虑动态链接到它。

然而,当来自LA的对象O从A传递到B时会发生什么

它实际上取决于对象
O
是什么,以及库
L
对它做了什么。如果
O
是一个完全依赖于存储在该对象中的状态的对象,那么一切都可能正常。但是,如果
O
不是,如果
O
依赖于全局状态或其他对象或某物的状态,则可能会出现问题


避免问题的最好方法是在两个DLL之间有适当的绝缘层。也就是说,你根本不应该在两者之间传递
O
,因为它们谈论的不是同一个
O
。一般来说,如果<代码> L 足够大,你需要在两个用户之间传递它的对象,那么它就足够大了,你可能应该考虑动态链接到它。

当卸载A时,对象O的代码就消失了。试图在O上调用方法将导致运行时错误。@David,这是真的吗?或者O在dll B中使用LB代码时是否存在?您创建了OA,然后卸载了它后面的代码。这总是以眼泪结束。@David:严格来说不必,尤其是当
O
是一个POD对象时。但是这样做是一个非常非常糟糕的主意。@Doug:链接器不一定会参与解析对O::foo的调用。对象O可能包含一个指向函数表的指针,以支持多态性,或者其他指向数据的指针,这些数据在卸载LA后将不再存在。(就此而言,取决于上下文,LA可能已经释放了O本身存储在其中的内存块!)卸载A时,对象O的代码已经消失。试图在O上调用方法将导致运行时错误。@David,这是真的吗?或者O在dll B中使用LB代码时是否存在?您创建了OA,然后卸载了它后面的代码。这总是以眼泪结束。@David:严格来说不必,尤其是当
O
是一个POD对象时。但是这样做是一个非常非常糟糕的主意。@Doug:链接器不一定会参与解析对O::foo的调用。对象O可能包含一个指向函数表的指针,以支持多态性,或者其他指向数据的指针,这些数据在卸载LA后将不再存在。(就此而言,取决于上下文,LA可能已经释放了O本身存储在其中的内存块!)当您尝试创建单例时,这可能会非常令人惊讶。这可能是最明显的结果,但我想知道您是否可以扩展--虚拟函数会发生什么情况?当对象O在A或B中时,调用哪个代码?在这些情况下会发生什么?当你试图创建一个单例时,这可能会非常令人惊讶。这可能是最明显的结果,但我想知道你是否可以扩展——虚拟函数会发生什么?当对象O在A或B中时,调用哪个代码?在这些情况下到底发生了什么?