我正在尝试将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:找到一个或多个乘法定义的符号
答案 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
(还有很多)从来没有一个人定义它。
因此解决方案非常简单:
CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
。__declspec(export|import)
。