包装C ++共享库时在C ++/CLI项目中链接错误 [英] Linking error while in C++/CLI project while wrapping C++ shared library

查看:136
本文介绍了包装C ++共享库时在C ++/CLI项目中链接错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to wrap C++ library to that managed projects can use it. The third party library I am using is a shared library. It's meant to link on load time. I have header files, .lib file which is DLL import library and .DLL file.

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

This is what I did so far:- 1. Created CLR project. 2. Added path for header file in C/C++->General->Additional Include Directories 3. Set 'Additional Library Directories' in Linker->General. 4. Added lib name in Linker->Input->Additional Dependencies

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

After I do that, I get LNK2005 linking error followed by LNK1169. The only thing I did after creating the project is including header file from C++ library which I am trying to wrap. What am I doing wrong?

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

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

推荐答案

实际上,我们是图书馆的创建者,经过长期的奋战,我们得以弄清问题所在.万一这对其他人有用,答案就在这里.

Indeed, we were the creators of the library and after a long battle, we were able to figure out the issue. In case it's useful for somebody else, here goes the answer.

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

The library was being generated using CMake, and to avoid having to export symbols by hand (using __declspec(export), we simply turned on

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS on)

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

However, doing that in a DLL implies that Visual Studio not only exports the symbols defined in the DLL itself, but also in its inherited dependencies (like the entire STL for example).

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

The previous (I'm not really sure why) is not a problem is you are linking this library as part of the building of an executable (as we do have a C++ EXE that successfully uses this DLL), but it's a major issue if you are linking the DLL against another DLL (which is the case for CLI/C++, where you're basically creating one DLL to wrap another DLL). In the latter, the CLI DLL will also try to import the symbols from the system, resulting in the redefinition previously displayed:

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),尽管其中包含std::exception::what(尽管其中许多DLL都未定义),但它包含std::exception::what.它本身.

One way to check this is to take a look of the export file (.def) generated by the base C++ DLL (not the CLI one), it contains std::exception::what (among many others), although that DLL never defined it by itself.

因此解决方案非常简单:

So the solution was rather simple:

  1. 关闭CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.
  2. 从DLL中显式导出/导入所需的符号(使用__declspec(export|import).
  1. Turn off CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.
  2. Export/import explicitly the desired symbols from the DLL (using __declspec(export|import).

这篇关于包装C ++共享库时在C ++/CLI项目中链接错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆