静态库链接了两次

时间:2015-07-03 14:58:40

标签: c++

我有以下设置:

  1. 静态库
  2. 链接到(1。)
  3. 的动态库
  4. 链接到(1.)和(2。)
  5. 的可执行文件

    来自静态库的代码现在已复制并存在于动态库和可执行文件中。

    问题:

    Data(全局变量,静态类成员)是否也重复并且可执行文件和dll是否看到相同的数据?

    Linux和Windows之间有区别吗?

    你会如何解决这个问题?

    编辑:

    感谢您的回答,我无法解释我的案件中究竟发生了什么。

    静态库没有导出/导入标志。 动态库帽子导出自己的符号。

    视窗:

    动态库有静态库的文本+数据段的副本。 可执行程序无法知道动态库已链接静态库,因为非静态库符号从外部可见。

    Linux的:

    动态库有一个静态库的文本数据段的副本。 动态库虽然包含了静态库中自己的符号表中的所有符号(文本和数据)。 - >可执行文件看到,动态库已经定义了静态库的所有符号,并且没有重新定义它们。

    这很糟糕,因为你通常想在linux和windows上使用相同的行为。

    1. 分享符号(默认在linux上)

      • 在将静态库链接到共享库时,对静态库中的所有符号添加dll导出命令。 __attribute__ ((dllexport))
      • 将静态库链接到可执行文件时添加dll import命令。 __attribute__ ((dllimport))
      • 代码和数据仅驻留在共享库中,可从外部链接
    2. Reduntant符号(在Windows上默认)

      • 您需要确保静态库的符号未包含在共享库的符号表中
      • __attribute__ ((visibility ("hidden")))关于gcc
      • 链接可执行文件时,无法在任何地方找到静态库中的符号,因此会再次包含它们。

2 个答案:

答案 0 :(得分:5)

据我所知,这取决于操作系统(因为C ++语言并没有说明库应该如何工作)。

在Windows上,你将获得两倍的代码和数据,更糟糕的是所有该库中声明的全局变量的两倍(!)

当您获得两个默认分配器并且在库上调用new而在另一个上调用delete时,静态链接程序中的标准库和使用它的库时会出现此问题,该对象将在new侧泄漏,并且该堆可能在delete侧被破坏。

我不知道有关其他操作系统的详细信息,但我预计可能会出现类似的问题

答案 1 :(得分:0)

IMO这是一个令人讨厌的情况,因为有两个可执行文件(exe和dll),每个可执行文件都包含代码和全局数据的实例。它们是独立构建的,无法共享其内存映射。

一个选项可能是让dll公开静态库所需的成员,以便exe可以直接链接到它们。