【问题标题】:multiply defined symbols using static lib使用静态库乘以定义的符号
【发布时间】:2014-12-18 08:42:58
【问题描述】:

我有一个将静态库链接到 Visual Studio(相同版本,相同机器)的应用程序。

这个库包含多个具有多个函数的 c 文件(像往常一样:)

举个例子

  • lib1.lib
    • file1.c
      • func_f1_1
      • func_f1_2
    • file2.c
      • func_f2_1
      • func_f2_2
  • prog1.exe
    • (链接 lib1.lib)
    • main.cpp
      • 使用func_f2_2
    • 奇怪的.c
      • func_f1_1(相同的签名,不同的定义)
      • func_f2_1(相同的签名,不同的定义)

lib1 是从 prog1.exe 独立构建的

在链接期间编译器会抱怨

lib1.lib(file2.obj): error LNK2005: _func_f2_1 already defined in strange.obj

链接器不会抱怨func_f1_1

我不完全理解这种错误,因为我希望链接器只从目标可执行文件中未定义的库中获取符号。

在我看来,链接器试图从 lib 中放入整个 obj 的内容,而不是仅放入函数。

我可以更改任何项目设置以使链接器在功能级别上工作吗? “函数级链接”在 lib 和程序项目的编译器属性中被激活。

【问题讨论】:

    标签: visual-c++ linker visual-c++-2010


    【解决方案1】:

    如果您的程序使用func_f2_2,则链接器会将定义func_f2_2 的对象文件lib1:file2.o 添加到对象列表中。该目标文件中的所有符号都链接到程序中。这包括func_f2_2func_f2_1 可能使用的所有变量。

    链接器不会抱怨func_f1_1,因为没有理由加载目标文件lib1:file1.o

    如果你需要替换func_f2_1,你还必须在strange.c中添加func_f2_2的定义。

    【讨论】:

    • 没有办法解决这个问题吗?更熟悉 gnu 工具链的人说这适用于 gcc。我一直认为链接将在符号级别而不是文件级别上完成。特别是如果功能级链接被激活。
    • @vlad_tepesch “我一直认为链接将在符号级别而不是在文件级别完成。” ——你总是想错了。 “有人说这适用于 gcc”——它不会,除非使用-ffunction-sections 命令行参数,这使它在函数级别而不是文件级别上运行(这是 不是默认行为,也不是没有成本)。
    • 很好地解释了链接器的工作原理:eli.thegreenplace.net/2013/07/09/…
    • @Employed 文章讨论了 GNU ld 的操作与 Microsoft Link 完全不同的地方,例如文件的顺序无关紧要,循环依赖由工具解决。
    • @harper 你错了:链接行上的文件顺序与 Microsoft Link 的相关性与包括 GNU ld 在内的所有其他链接器一样。 msdn.microsoft.com/en-us/library/hcce369f.aspx
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 2016-09-20
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多