在 C++ 中使用多个静态库解决冲突

Posted

技术标签:

【中文标题】在 C++ 中使用多个静态库解决冲突【英文标题】:Conflict resolution using multiple static libraries in C++ 【发布时间】:2012-02-07 20:17:50 【问题描述】:

我有两个来自 «vendor1» 和 «vendor2» 的静态库:

vendor1.libvendor1.h; vendor2.libvendor2.h

在文件中,vendor1.h。有以下声明:

double Min();

在文件中,vendor2.h。有以下声明:

double Min();

在我的客户端文件中:

include "vendor1.h"  
include "vendor2.h"  
double x = Min();

它默认调用vendor1.h。我尝试引入命名空间:

   namespace vendor1   
    include "vendor1.h"
   

   namespace vendor2   
    include "vendor2.h"
   

调用以下函数

double xx = vendor2::Min();

我收到以下链接器错误:

Client.cpp 1>Client.obj:错误 LNK2019:引用了未解析的外部符号“double __cdecl vendor2::Min(void)”(?Min@vendor2@@YANXZ) 在函数 _wmain 1>c:\temp\Client\Debug\Client.exe 中:致命错误 LNK1120: 1 个未解决的外部问题

如何在不为每个包装器创建包装器的情况下解决此问题?

【问题讨论】:

丑,但你可以patch the symbol names。 C 链接不支持名称空间。如果你想静态链接这两个库,你无法真正解决这个问题。如果可以的话,您可以尝试动态加载它们。 谢谢。这个练习/回答了与命名空间和名称修改相关的明确概念。 【参考方案1】:

如果您有两个名称冲突的静态库,您将无法静态链接您的程序!静态链接器会去寻找与未定义符号匹配的第一个符号并选择它。将名称包装到命名空间中没有帮助:这会更改库中预期的命名空间。您刚刚发现为什么命名空间是一件好事。

如何解决问题?我不知道基于 C++ 标准的方法。实际上,您可以做一些事情:创建一个动态库,将其转发给您的冲突函数,但将名称放入单独的名称空间(或使用不同的名称)。动态库与单独的静态库链接,即此时不会发生冲突。您可能还需要避免从共享库中的符号中看到底层名称。具体如何完成取决于编译器,我不知道由谁来处理 MSVC++ 这类事情。

【讨论】:

【参考方案2】:

如何将函数包装到不同的命名空间中?

vendor1_wrapper.h

namespace vendor1 
    double Min();

vendor1_wrapper.cpp

#include "vendor1_wrapper.h"
#include "vendor1.h"

namespace vendor1 
    double Min()
    
        return Min();
    

vendor2_wrapper.h

namespace vendor2 
    double Min();

vendor2_wrapper.cpp

#include "vendor2_wrapper.h"
#include "vendor2.h"

namespace vendor2 
    double Min()
    
        return Min();
    

现在您可以使用命名空间(您的客户端文件)来使用函数:

#include "vendor1_wrapper.h"
#include "vendor2_wrapper.h"

...

vendor1::Min();
vendor2::Min();

【讨论】:

以上是关于在 C++ 中使用多个静态库解决冲突的主要内容,如果未能解决你的问题,请参考以下文章

论项目中静态库符号冲突的几种解决方式

论项目中静态库符号冲突的几种解决方式

iOS合并lib(.a)库的可用方法(可用于解决duplicate symbol静态库冲突)

请教Makefile中依赖自已写的静态库问题

静态库冲突的解决办法:duplicate symbol

将静态库转换为 DLL 在 main 之前导致访问冲突