调用非托管dll常出现的bug及解决办法

Posted on   云起  阅读(13)  评论(0编辑  收藏  举报  

转自http://www.51testing.com/html/00/n-832200.html

  C和C++有很多好的类库的沉淀,在.NET中,完全抛弃它们而重头再来是非常不明智的、也是不现实的,所以,我们经常需要通过Pinvoke来使用以前遗留下来的非托管的dll。就.NET中使用非托管的dll经验而言,经常碰到的问题至少有两个,它们都是通过在运行时抛出异常来体现的。

  1、试图加载格式不正确的程序

  出现这种异常,通常是.NET应用程序的“目标平台”与非托管dll的平台不一样。

  一般,在使用VS开发.NET的应用程序和类库时,默认的目标平台为“Any CPU”,即会在运行时可根据CPU类型自动选择X86或X64,拥有这样的能力是因为.NET编译后的程序集是基于IL的,在运行时,CLR才会将其JIT发射为X86或X64的机器码。

  而C或C++编译生成的dll就是机器码,所以,其平台的决策是在编译时决定的。通过编译选项的设置,我们可以将C/C++项目编译为X86的dll或者X64的dll。

  所以,在调用了非托管dll的.NET项目中,也需要将其目标平台属性设为与非托管的dll的运行平台完全一致。通常遗留下来的非托管dll都是基于x86的,所以,在调用了这类非托管dll的.NET项目中,就将其目标平台属性设为“X86”。

  可根据“项目->属性->生成->目标平台”找到该设置:

  2、无法加载dll,找不到指定的模块

  运行调用了非托管的.NET应用程序有时会出现这种异常,可是比较郁闷的是,这种异常并不是在所有的电脑上都会出现,就经验来说,它只是在少部分电脑上出现,而在绝大部分电脑上运行都是正常的。我们在开发语音视频录制组件MFile时,就遇到过这个问题,当时很是头疼。

  如果出现这种情况,很大的可能就是那少部分电脑上没有安装VC++运行时(CRT),或者是CRT安装不正确导致的。好用的解决方案有两种:

  (1)在C盘下找到了下列文件:msvcm80d.dll、msvcp80d.dll、msvcr80d.dll、Microsoft.VC80.DebugCRT.manifest。把这几个文件拷贝到目标机器上,放到运行目录下或放到system32下,就可以了。

  注意,一般这几个文件都有多个版本,位于不同的文件夹下,要观察其文件夹的名称:是x86还是x64的、是debug的还是release的、以及是否要MFC的,这些选择要与非托管dll的信息一致。

  (2)如果有非托管dll的源码,那就修改编译选项,重新编译一下:将/MD或/MDd 改为 /MT或/MTd,这样就实现了对VC运行时库的静态链接,在运行时就不再需要上述几个dll了。


编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义

随笔 - 119, 文章 - 0, 评论 - 3, 阅读 - 4066

Copyright © 2025 云起
Powered by .NET 9.0 on Kubernetes

点击右上角即可分享
微信分享提示