【问题标题】:A procedure imported by {dll} could not be loaded无法加载由 {dll} 导入的过程
【发布时间】:2013-05-23 01:27:29
【问题描述】:

我有几个非托管 C++ 编写的 lib 文件,我需要链接到托管 C++ dll。
然后我需要从 C# 应用程序调用这个托管 C++ 的函数。

第一步没问题 - 创建了托管 C++ dll,我可以通过 ildasm 看到它导出了我需要的函数。但是,当我尝试从我的 C# 编写的测试应用程序中调用此函数时,它会显示:

未知模块中出现“System.IO.FileLoadException”类型的未处理异常。
无法加载由 {MyManagedCPP.dll} 导入的过程。

此消息来自 VS2010。
我做了一个简单的实验 - 从托管 C++ dll 中的所有 lib 文件中删除依赖项并重建它。
有了这个更改就可以了 - 应用程序启动,我可以从 C# 测试应用程序调用托管 C++ dll 的函数。

当 dll 与 lib 文件具有静态链接时,是否无法通过设计调用托管 c++ 函数?技术限制?还是有一些解决方法?

谢谢

【问题讨论】:

  • 看看 System.Runtime.InteropServices。特别是DllImport["my.dll']。请注意放置 Dll 的位置(它们需要位于项目定义的工作目录中,不一定位于 exe 旁边。
  • 不,我认为这里不需要 DLLImport。最后,我管理了 dll 和管理的 exe。但是 [DLLImport] “表明属性方法由非托管动态链接库 (DLL) 作为静态入口点公开。”这不是我的情况。

标签: c# static-linking managed-c++ ildasm


【解决方案1】:

毫无疑问,您对本机 DLL 存在隐式依赖。从这个问题中不清楚这可能是什么 DLL。例如,它可能是 msvcrxx.dll,本机 C++ 代码的运行时支持库。这将是相当糟糕的,你不想混合 CRT 版本。这种缺失的 DLL 会阻止加载 C++/CLI 程序集,从而产生 FileLoadException。

如果您不知道该 DLL 可能是什么,那么您可以使用 SysInternals 的 ProcMon 实用程序。跟踪将显示程序正在搜索 DLL 而没有找到它。如果是 msvcrxx.dll,请确保使用与构建 C++/CLI 程序集相同的编译器版本重新构建 .lib 文件。如果是其他内容,请确保将该 DLL 复制到构建目录。

【讨论】:

  • 遗憾的是我无法重建 lib 文件 - 没有源代码。而且我也知道它们是在我使用 VS2010 时使用 VS2008 构建的。当我收到错误时,我在进程资源管理器中看到已加载托管 dll 并且也加载了非托管 dll(取决于托管 dll)。看起来这是使用不同版本的编译器的问题。
  • 好吧,从技术上讲,如果 DLL 设计得当,则可以在不匹配的情况下幸存下来。但是,您需要在您的计算机上安装正确版本的 msvcr90.dll 才能解决 FileLoadException。
  • 谢谢,这让我找到了答案。我们有一个 C++/CLI 库,它链接到一些“真正的 C++”库;-) 我的同事用 VS2019 重建了 CLI 库,这对链接做了一些奇怪的事情。我没有时间深入研究它,但是当我在 Dependency Walker 中比较两者(他的构建与我的构建)时,我可以清楚地看到我们链接的本机 c++ 库中有未解析的外部函数。
猜你喜欢
  • 2012-09-16
  • 1970-01-01
  • 2016-01-16
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 1970-01-01
  • 1970-01-01
  • 2017-06-26
相关资源
最近更新 更多