如何将本机 C++ 静态库链接到托管 C++ 程序集

Posted

技术标签:

【中文标题】如何将本机 C++ 静态库链接到托管 C++ 程序集【英文标题】:How to link a native c++ static library into a managed c++ assembly 【发布时间】:2015-04-30 17:03:19 【问题描述】:

我已经搜索了几天,但找不到我的问题的答案,这似乎与人们提出的其他问题有所不同,但我发布了一个非常具体的问题。

我有一个托管 C++ 程序集,我的“客户”使用它来链接 C#/.NET 项目。此程序集毫无问题地引入 OpenSSL 静态 c++ 库,但不会引入我的非托管 C++ 静态库(称为“MyLib.lib”)。

起初这是因为“MyLib.lib”使用了 CRT 的静态链接,但我将其切换为使用 CRT 的 DLL 版本。不幸的是,所做的只是改变了问题。

现在,当我编译我的托管 C++ 程序集时,它正在寻找“MyLibmdd.lib”——这当然不存在。当我将链接器输入指定为“MyLib.lib”时,为什么它会寻找这样的东西?而它认为“MyLibmdd.lib”中有什么,为什么需要它存在?

它不需要“libeay32mdd.lib”或“ssleay32mdd.lib”,那为什么它对我的静态库有不同的处理呢?

最终,我知道我应该能够将“MyLib.lib”拉入托管 C++ 项目,因为其他人已经做到了(包括 OpenSSL)。因此,我似乎没有意识到应该如何构建“MyLib.lib”。

有什么想法我现在应该仔细检查一下吗?我正在使用 Visual Studio 2013。

谢谢!

【问题讨论】:

有不同的构建可以链接。链接到 DLL CRT 时,您选择它为多线程和调试(这就是 mdd 后缀的含义)。链接器假设您的库也有不同的构建,并寻找类似的后缀以确保所有库都匹配 不确定我是否关注。 “MyLib.lib”是用 /Md 编译的,托管 C++ 程序集也是如此。所以托管 C++ 程序集应该已经拥有它正在寻找的东西。我尝试从托管 C++ 程序集项目的链接器输入中删除“MyLib.lib”,但后来它抱怨找不到“MyLib.lib”。所以我把它放回去,现在它想要“MyLibmd.lib”(在发布模式下)。为什么它需要两个版本的.lib?如果是这样,那么为什么“MyLib.lib”项目不吐出两个 .lib 文件?同样,它不会从其他开源 .lib 文件中寻找相同的内容。 将调试库和发布库链接在一起存在问题。所以据我所知 MyLib.lib 被认为是“图书馆家族”的名字。链接哪个特定库由编译设置自动添加的后缀定义。对于给定的编译器设置,您确实必须至少有两个库(一个调试和一个发布)并制作适当的后缀 ***.com/questions/11658915/… 我确实有一个调试版本和一个发布版本的 MyLib.lib。它们具有相同的名称,但进入不同的文件夹“调试”和“发布”文件夹。由于我手动将我的输出文件命名为 MyLib.lib,我是否需要在输出名称字段中自己添加后缀“md”和“mdd”?我想如果我指定了输出名称 MyLib.lib,然后在它专门链接到 MyLib.lib 的消费项目中,一切都应该匹配,对吧? 我想是的,但你应该试试。根据我的经验,当我在构建过程中重建和使用 BOOST 库(来自 www.boost.org)时,我会完成所有库(调试、发布、mt、st)并附加后缀以指示哪个是调试或发布或.. ...在我构建应用程序时链接正确的库之后 【参考方案1】:

问题确实是在许多地方都有#pragma comment(...) 行,这阻止了以我的方式命名输出库。评论了这些,到目前为止一切似乎都很好。

【讨论】:

以上是关于如何将本机 C++ 静态库链接到托管 C++ 程序集的主要内容,如果未能解决你的问题,请参考以下文章

如何将 MKL v9.x 静态链接到托管 C++ DLL 以计算 FFT?

用于 C++ 的 C# 包装器,但仅编译为静态库

托管 c++ 库,它是如何工作的?

如何将托管 c++ 库导入 C# 应用程序(目标 .net 版本 3.5)

如何将 C++ 本机对象编组到托管 C++ CLI

如何重新导出 CLR c++ 静态库