包装C ++共享库时在C ++ / CLI项目中链接错误

时间:2018-09-12 05:15:03

标签: c++ c++-cli native wrapping

我正在尝试将C ++库包装为托管项目可以使用它的库。我正在使用的第三方库是共享库。这是为了链接加载时间。我有头文件,.lib文件(这是DLL导入库)和.DLL文件。

这是我到目前为止所做的:  1.创建了CLR项目。  2.在C / C ++->常规->其他包含目录中添加了头文件的路径 3.在“链接器”->“常规”中设置“其他图书馆目录”。  4.在Linker-> Input-> Additional Dependencies

中添加了lib名称

执行完此操作后,出现LNK2005链接错误,接着是LNK1169。创建项目后,我要做的唯一一件事就是包括要包装的C ++库的头文件。我在做什么错了?

错误LNK2005:“公共:虚拟字符const * __cdecl std :: exception :: what(void)const”(?what @ exception @ std @@ UEBAPEBDXZ)已在...中定义 严重错误LNK1169:找到一个或多个乘法定义的符号

2 个答案:

答案 0 :(得分:0)

您可能正在尝试静态链接标准库的两个不同版本。您是否已与该库的第三方提供者联系,以确定他们用来构建该库的Visual Studio / C ++版本?

此外,在对第三方库的问题进行故障排除时,在尝试构建C ++ / CLI库之前,应尝试链接一个简单的命令行可执行文件。

是的,如果可能的话,应该将本机C ++库静态链接到C ++ / CLI dll。这将使部署更加容易。大概这将是您的C#应用​​程序将使用的唯一C ++ / CLI程序集。

答案 1 :(得分:0)

的确,我们是图书馆的创建者,经过长期的战斗,我们得以找出问题所在。万一这对其他人有用,答案就在这里。

该库是使用CMake生成的,为避免手动导出符号(使用__declspec(export),我们只需打开

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS on)

但是,在DLL中执行此操作意味着Visual Studio不仅导出DLL本身中定义的符号,还导出其继承的依赖项(例如,像整个STL)。

以前的(我不太确定为什么)没有问题,因为您正在链接该库作为构建可执行文件的一部分(因为我们确实有一个成功使用此DLL的C ++ EXE),但这是一个如果将DLL链接到另一个DLL(CLI / C ++就是这种情况,基本上是在创建一个DLL来包装另一个DLL),则这是一个主要问题。在后者中,CLI DLL还将尝试从系统导入符号,从而导致先前显示的重新定义:

error LNK2005: "public: virtual char const * __cdecl std::exception::what(void)const " (?what@exception@std@@UEBAPEBDXZ) already defined in ... fatal error LNK1169: one or more multiply defined symbols found

一种检查方法是查看由基本C ++ DLL(不是CLI生成的)生成的导出文件(.def),尽管其中包含DLL,但它包含std::exception::what(还有很多)从来没有一个人定义它。

因此解决方案非常简单:

  1. 关闭CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
  2. 从DLL中显式导出/导入所需的符号(使用__declspec(export|import)