【问题标题】:Referencing an unmanaged C++ Project From a CLI C++ Project从 CLI C++ 项目引用非托管 C++ 项目
【发布时间】:2012-09-19 07:39:49
【问题描述】:

我正在尝试创建一个 CLI DLL 来桥接我的非托管 C++ 可执行项目和另一个托管项目,所有这些都在一个 Visual Studio 解决方案中。

不过,我遇到的问题更早:我无法在我的新 CLI 项目中链接引用非托管 C++ 项目。我已经包含了所需的 .h 文件,并在 CLI 项目中添加了对非托管项目的引用。编译成功,但是出现了之前没有遇到过的链接错误:

错误 2
错误 LNK2028:未解析的令牌(0A000088)“公共:__cdecl ...

我在项目属性中添加了一个引用并包含了 .h 文件。

谢谢

【问题讨论】:

  • 您不能以与托管 dll 相同的方式“引用”非托管 dll。相反,您必须将它们对应的 .lib 文件作为输入添加到链接器

标签: c++ visual-studio-2010 visual-studio compilation


【解决方案1】:

似乎链接器缺少其他项目的一些中间信息。我真的不记得“引用”本机项目是否会自动设置链接阶段。我真的觉得你说“引用”很奇怪。对我来说,“引用”这个词有点局限于.Net的世界程序集,因为 VS 中的“添加引用”,这使得没有人关心包含/库,并且由于显而易见的原因,本机 dll 无法使用 IIRC。如果您的意思是您手动配置了链接器选项,请原谅我 :)

如果不是 - 请说明您是如何引用本机模块的。

无论哪种方式,如果“引用”较早工作,如果您重命名项目,文件名可能会不同步,可能文件时间戳有点偏离并且 VS 没有注意到新版本。有时简单的清除和重建神奇地帮助。如果没有,您可以尝试手动删除Debug/Release/Bin/Obj文件夹,然后重新构建。

要尝试诊断,第一步是查看链接器作为输入给出的内容:在 C++/CLI 项目的项目属性页面中,检查 Linker->CommandLine 并查看名称类似于“myOtherNativeCppProjectName”的文件.lib”在那里可见。如果不是 - 这就是问题所在,只需将其添加到 previos 链接器页面上的链接器选项中,或重新添加引用,然后清理、重建并查看会发生什么。

要说更多,您必须发布整个错误消息 - 此错误消息在函数名称处被截断,因此很难判断它是您的函数,还是某些缺少的库模块。随着编译阶段成功并且问题出在链接 - 您是否 100% 确定您已实现该功能?我的意思是,正确的 .h 肯定提供给 C++/CLI 项目,但是正确的 .cpp 文件是否与本机中包含的 .h 文件匹配?忘记添加一个文件也很常见。或者忘记实例化模板.. 或者在 .H 和 .CPP 之间输入错误的类/函数名..

【讨论】:

  • 非托管 C++ 项目是可执行文件,因此不会创建 .lib 文件,因此我无法在任何地方找到对 lib 文件的引用。是否可以引用其他项目的 obj 文件?
  • 不,.obj 文件是不应在项目构建之外使用的中间文件。它们是临时产品,而不是最终产品。它们实际上可能会变得有用,因为 .obj 建议使用静态库中的原始模块,但将这种尝试作为最后的手段。 .exe 文件也可以生成 .lib 文件,就像普通的 dll 一样——它们是否包含可导出符号都是问题。您是否在 .exe 的代码中使用过__declspec(dllexport)?如果不是 - 那么没有符号是可导出的,这就是不生成 LIB 的原因 - 它在为空时被跳过。
  • 所以我很清楚:如果我想包含我的可执行项目中的功能,我需要将其编译为 lib 或在我需要的任何功能上使用 __declspec(dllexport)?跨度>
  • 您不必“将其编译为 lib”。 .lib 文件是构建 .dll 或 .exe 文件的副作用。该文件是所有功能的列表。此 .dll 或 .exe 可供其他人使用的“符号”。您完全必须在要公开的东西上使用 __declspec(dllexport) ,否则每个符号都将被设为“私有”并隐藏,或者您可能认为它在编译后将其“未命名”或优化。 __declspec(dllexport) 将标记的函数或类固定为“必须以这种确切形式存在”和“必须在 .lib/.exp 文件中列出”。
  • 有一个“.dll+.lib”组合(或“.exe+.lib”)。 “.dll+.lib”对实际上是动态库“.dll”和一个小的帮助/包装静态库“.lib”。 “.lib”文件总是某种静态库。如果您将项目构建为动态库(如 DLL),您将获得一个 DLL,而小库是一个代理/帮助程序,它将所有函数调用重新反弹到实际 DLL。您也可以构建为静态库,如 LIB - 然后只生成 .lib,并且 .lib 包含所有内容并且没有 DLL 文件。所以,如果你想把它分开,不要“编译为 LIB”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-26
  • 1970-01-01
  • 2014-12-10
  • 1970-01-01
  • 2011-07-03
  • 2018-04-04
相关资源
最近更新 更多