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

  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了。

时间: 2024-11-03 10:19:19

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

非托管dll-C#调用非托管DLL,报“其他内存已损坏”,请问怎么解决呢?

问题描述 C#调用非托管DLL,报"其他内存已损坏",请问怎么解决呢? 定义: [DllImport("BSEncrypt.dll")] public static extern bool MD5String(ref string instr, int inlen, ref string outstr, int outlen); 调用: String ls_MD5Password = new String('', 100); string as_Password =

关于c#动态调用非托管DLL的内存释放问题

问题描述 本人由于客户的需要,需要在程序的运行过程中,动态加载不同的DLL.这与直接调用非托管DLL不一样.下面这个帖子中的第三个方法很好的说明了如何动态调用非托管DLL.http://blog.csdn.net/pansiom/article/details/568096#comments为了方便使用,我把文中的方法弄成了一个DLDApi类,如下usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Re

C#调用非托管DLL,窗口关闭后报错,求教!

问题描述 这几天在做一个医院的报销接口系统,对方提供的接口是一个DLL动态库,暂且叫做A.DLL,是delphi的.其中A.DLL中封装的各功能方法,我都能正常调用,也都执行正常,但是唯一一点不足的就是,有的时候我关闭浏览器(我们的系统是BS)的时候,就会弹出下面的那个错误提示:无效的窗口句柄.以前做此类报销接口的时候其他厂商也很多是非托管DLL,但是没有出现过此类情况.百度了很长时间,有的说资源释放问题,有的说是A.DLL自身没有做好处理,各种各样的方案吧.然后自己又写了一个CS的Demo来测

关于c#调用非托管dll的问题

问题描述 vc6中的定义如下:注册数据流直读取回调:RegisterStreamDirectReadCallback()函数:intRegisterStreamDirectReadCallback(STREAM_DIRECT_READ_CALLBACKStreamDirectReadCallback,void*Context)参数:STREAM_DIRECT_READ_CALLBACKStreamDirectReadCallback数据流准备好时会调用该函数Void*Context调用回调函数时

有关c# 调用vc++编写的非托管DLL、socket编程等相关知识的讲的比较详细的书籍

问题描述 有关c# 调用vc++编写的非托管DLL.socket编程等相关知识的讲的比较详细的书籍 学习c# 调用vc++编写的非托管DLL.socket编程等相关知识的讲的比较详细的书籍都有哪些?(最好是基于VS2008的) 解决方案 c#调用非托管C++生成的dllc# 调用 C++ 非托管 DllC#调用非托管dll 解决方案二: 这样一个知识点,最好是 Baidu/Google 查找来解决 书上的内容,没有网络上的丰富

c#调用dll-调用非托管dll中类的方法

问题描述 调用非托管dll中类的方法 如何用c#来调用c++生成的dll文件中的类的方法? 解决方案 重写为C#的类,否则没办法

asp.net C#调用托管DLL和非托管DLL文件的区别

asp教程.net c#调用托管dll和非托管dll文件的区别 托管dll文件,可以在dotnet环境通过 "添加引用" 的方式,直接把托管dll文件添加到项目中.然后通过 using  dll命名空间,来调用相应的dll对象 .     非托管dll文件,在dotnet环境应用时,通过 dllimport 调用.    c# 调用非托管dll文件.dll文件是用c语言编写的. 如下: 1:结构定义   rditag_t     rditag_t结构定义了测点的结构   typedef

.net 服务多线程 调用非托管C++DLL 如何防止 服务崩溃?

问题描述 .net 服务多线程 调用非托管C++DLL 如何防止 服务崩溃? 有一个.net服务,服务中开了多线程.其中有一线程会去调用非托管C++DLL,并阻塞等待其返回值.其他线程同步做文件处理.数据状态更新等操作.现在调用非托管C++DLL的线程会因为非托管代码的问题,崩溃.这样整个服务也就崩溃了!需要人工去服务器上重启该服务!请问:如何防止整个服务崩溃?是否可以捕获非托管C++中的错误.因为已经try catch了,但什么都捕获不到,直接服务崩溃! 解决方案 这个应该要想办法解决C++

C#调用非托管C++DLL中的函数接口

问题描述 C#调用非托管C++DLL中的函数接口(有生成的DLL文件和Lib文件)怎么引用?引用项添加不了 解决方案 解决方案二:使用DllImport,添加引用只能针对.NET控件或COM组件.解决方案三:DllImport具体搜p/Invokehttp://www.cnblogs.com/xuqiang/archive/2010/12/21/1953355.html解决方案四:C++DLL中的函数中还调用了openCV的函数,能说一下怎么整么?解决方案五:引用3楼qq_28744297的回复