C++ 静态库链接两次
我有以下设置:C++ 静态库链接两次,c++,C++,我有以下设置: 静态库 链接到(1)的动态库 链接到(1.)和(2.)的可执行文件 来自静态库的代码现在被复制并出现在动态库和可执行文件中 问题: 数据(全局变量、静态类成员)是否也重复,可执行文件和dll是否看到相同的数据 Linux和Windows之间有区别吗 你将如何解决这个问题 编辑: 谢谢你的回答,我现在可以准确地解释我的情况了 静态库没有导出/导入标志。 动态库已导出其自己的符号 窗口: 动态库具有静态库的文本+数据段的副本。 可执行程序无法知道动态库已链接到静态库,因为从外部可以看
- 将静态库链接到共享库时,对静态库中的所有符号添加dll导出命令<代码>\uuuuu属性(dllexport))
- 将静态库链接到可执行文件时添加dll导入命令<代码>属性(dllimport))
- 代码和数据只驻留在共享库中,并且可以从外部链接
- 您需要确保静态库的符号不包括在共享库的符号表中
- gcc上的属性((可见性(“隐藏”))
- 链接可执行文件时,静态库中的符号在任何地方都找不到,因此它们会再次被包含
new
,在另一个库上调用delete
,则会出现此问题,对象将在new
端泄漏,堆可能在delete
端损坏
我不知道其他操作系统的详细信息,但我预计可能会出现类似的问题。这是一个糟糕的情况,因为有两个可执行文件(exe和dll),每个文件都有其代码实例和全局数据。它们是独立构建的,不能共享内存映射
一个选项是让dll公开静态库所需的成员,以便exe可以直接链接到它们。是的,数据是重复的。您可以使用动态库来解决它。@UmNyobe:已经有一个DLL;创建另一个没有任何帮助,因为它不会与第一个共享全局数据。库是预编译的还是作为源代码提供的?+1用于新建/删除技巧:我过去遇到过这种情况,并很快学会了避免使用异构构建。如果所有库调用都正常运行(也就是说,它们不观察或修改任何全局状态)可以使用静态链接,因为代码可能更高效/小(只包括您正在使用的符号),在所有其他情况下,我建议不要使用它。在Linux上,数据似乎没有被复制。@dari我刚刚测试了这个,如果您配置链接器,使其不从静态库导出符号(我可以用不太小的努力做到这一点)在linux和mac os中也会得到类似的效果。发现此类问题的一种方法是使用valgrind。它将报告一个“无效自由”,后跟分配变量的代码位置(例如全局),以及尝试释放它的两个代码位置。如果您查看这两个释放,它们很可能指向两个不同的库,这是同一代码存在两次并且运行不正确的原因。我是否理解您的答案正确:在dll中重新声明静态库中的所有变量和函数,以便不必链接到静态库。是的,这就是我的意思,希望链接器会同意。库的头将以三种版本存在:编译静态的标准、导出以构建dll和导入exe。