静态库链接了两次
Static library linked two times
我有以下设置:
- 静态库
- 链接到(1(的动态库
- 链接到(1.(和(2.(的可执行文件
来自静态库的代码现在被复制并出现在动态库和可执行文件中。
问题:
数据(全局变量、静态类成员(是否也重复,可执行文件和dll是否看到相同的数据?
Linux和Windows之间有区别吗?
你将如何解决这个问题?
编辑:
谢谢你的回答,我现在可以准确地解释我的情况了。
静态库没有导出/导入标志。动态库有自己的符号导出。
Windows:
动态库具有静态库的文本+数据段的副本。可执行程序不知道动态库已经链接了静态库,因为从外部看不到任何静态库符号。
Linux:
动态库具有静态库的文本数据段的副本,并将静态库中的所有符号(文本和数据(包含在自己的符号表中。->可执行文件看到,动态库已经定义了静态库的所有符号,并且没有重新定义它们。
这很糟糕,因为您通常希望在linux和windows上有相同的行为。
- 共享符号(linux上的默认值(
- 将静态库链接到共享库时,在静态库的所有符号上添加dll导出命令。
__attribute__ ((dllexport))
- 将静态库链接到可执行文件时,添加dll导入命令。
__attribute__ ((dllimport))
- 代码和数据仅驻留在共享库中,并且可以从外部链接
- 取消标记符号(窗口上的默认值(
- 您需要确保静态库的符号不包括在共享库的符号表中
- gcc上的
__attribute__ ((visibility ("hidden")))
- 当链接可执行文件时,静态库中的符号在任何地方都找不到,因此它们会再次包含在内
据我所知,这取决于操作系统(因为C++语言对库应该如何工作没有太多说明(。
在windows上,您将获得两倍的代码和数据,更糟糕的是,所有都是该库中声明的全局变量的两倍(!(
当静态链接程序中的标准库和使用该库的库时,当您获得两个默认分配器,并且如果在一个库上调用new
,在另一个库调用delete
,则对象将在new
侧泄漏,堆可能在delete
侧损坏。
我不知道其他操作系统的详细信息,但我预计类似的问题可能会出现
IMO这是一个令人讨厌的情况,因为有两个可执行文件(exe和dll(,每个文件都有它们的代码实例和全局数据。它们是独立构建的,不能共享它们的内存映射。
一个选项可以是让dll公开静态库所需的成员,以便exe可以直接链接到这些成员。
相关文章:
- 创建一个棋盘格或"Interweave"两个链接列表。IE 更改两个链表的指针
- CMake 库链接使用两个不同的编译器版本
- 如果包含映射的静态库与可执行文件和动态库链接,静态映射(变量)是否会被多次释放?
- 如何使用模板元编程在自由函数C++链接两个不相关的类
- C++ 分段错误:11 错误,同时编码将两个数字相加的链接列表
- 链接两个使用 c++ 构建的库_static
- 当我链接两个静态C++库时,我可以在两个主函数库中有两个主要功能吗?
- 调用函数一次用于动态链接库,一次从可执行文件调用函数
- C++:链接库两次,全局构造函数运行两次吗?
- 如何使用超载 运算符组合两个链接列表
- 深度使用两个链接列表的邻接列表的首次搜索C 实现
- 确实将静态库链接了两次重复
- 我如何合并C 中的两个链接列表
- Android makefile 链接两次
- qmake:如何链接一个库两次
- 通过两次链接同一个库来解决循环依赖关系
- 在链接两个对象文件时,使用#ifndef防止定义一个函数两次
- 链接库两次,可执行文件大小
- CMake链接opencv两次打乱编译器命令顺序
- 静态库链接了两次