托管DLL和非托管DLL的区别
狭义解释讲,托管DLL就在Dotnet环境生成的DLL文件。非托管DLL不是在Dotnet环境生成的DLL文件。

托管DLL文件,可以在Dotnet环境通过 “添加引用” 的方式,直接把托管DLL文件添加到项目中。然后通过 Using DLL命名空间,来调用相应的DLL对象 。
非托管DLL文件,在Dotnet环境应用时,通过引入 using system.Runtime.InteropServices;再在代码中通过DllImport 调用。

功能:通过c#调用c++编写的DLL。

实现:用delegate申明函数委托进行调用,可进行回调并应用指针.

遇到的问题点:

1、getProcAddress返回的值是0,无法获得NATIVE DLL中的导出函数
检查调用的函数名和c++项目中的是否一致;

2、查看c++ dll的函数名
VIEWDLL可以查看导出dll函数的名称

3、托管调试助手 "PInvokeStackImbalance":“对 PInvoke 函数“**.**+_DLL_Test::Invoke”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。”

程序可以执行以及返回正确结果,但仍然报错。

解决方案在我的另一篇博客 https://blog.csdn.net/u012482453/article/details/102894850

4、exception 值不能为 null。\r\n参数名: ptr System.ArgumentNullException
首先查看c++生成的DLL路径是否正确,以及调用的函数名是否正确
其次dll需要是c++项目生成的才可以,一开始我用c#项目生成了dll,无法用该方式调用

5、System.RuntimeType typeof DeclaringMethod 引发了类型 System.InvalidOperation
一开始觉得是typeof()报错,觉得是委托类型或传进的参数不对,后来发现是因为dll是c#生成导致的。

C#中,先定义将DLL函数地址转换成委托的类,方法以及封装参考: https://www.cnblogs.com/zeroone/p/3681379.html

C#调用C++的函数还有一种方法是用delegate申明函数委托进行调用,这种方法略显麻烦,但是可以进行回调并应用指针.

在C#中,定义一个类,用来把DLL中函数地址转换成委托:

public class DLLWrapper{///<summary>/// API LoadLibrary///</summary>[DllImport("Kernel32")]public static extern int LoadLibrary(String funcname);///<summary>/// API GetProcAddress///</summary>[DllImport("Kernel32")]public static extern int GetProcAddress(int handle, String funcname);///<summary>/// API FreeLibrary///</summary>[DllImport("Kernel32")]public static extern int FreeLibrary(int handle);///<summary>///通过非托管函数名转换为对应的委托, by jingzhongrong///</summary>///<param name="dllModule">Get DLL handle by LoadLibrary</param>///<param name="functionName">Unmanaged function name</param>///<param name="t">ManageR type对应的委托类型</param>///<returns>委托实例,可强制转换为适当的委托类型</returns>public static Delegate GetFunctionAddress(int dllModule, string functionName, Type t){int address = GetProcAddress(dllModule, functionName);if (address == 0)return null;elsereturn Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);}///<summary>///将表示函数地址的IntPtr实例转换成对应的委托, by jingzhongrong///</summary>public static Delegate GetDelegateFromIntPtr(IntPtr address, Type t){if (address == IntPtr.Zero)return null;elsereturn Marshal.GetDelegateForFunctionPointer(address, t);}///<summary>///将表示函数地址的int转换成对应的委托,by jingzhongrong///</summary>public static Delegate GetDelegateFromIntPtr(int address, Type t){if (address == 0)return null;elsereturn Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);}}
//函数封装DLL中的函数, hModule()函数的作用是取得DLL的地址,用在多个输出函数中private int hModule(){int _hModule = DLLWrapper.LoadLibrary(DLLPATH);if (_hModule == 0){return 0;}return _hModule;}//用delegate声明函数delegate void _amDBRInitialize (int mid, ref int errid);private void amDBRInitialize(){try{_amDBRInitialize amf = (_amDBRInitialize)DLLWrapper.GetFunctionAddress(hModule(), "amDBRInitialize", typeof(_amDBRInitialize));amf();}catch (Exception e){throw e;}}

C#调用非托管DLL--[1]基本步骤相关推荐

  1. 关于C#调用非托管DLL,报“内存已损坏的”坑,坑,坑

    因客户需求,与第三方对接,调用非托管DLL,之前正常对接的程序,却总是报"内存已损坏的异常",程序进程直接死掉,折腾到这个点(2018-05-11 00:26),终于尘埃落定,直接 ...

  2. 使用C#调用非托管DLL函数

    由于工作需要,学习了GDI+编程的一些知识.其中看到了一个比较好的Demo,深入的了解后,却发现自己对如何用C#调用非托管DLL函数也有了更好的理解,于是整理了一下,跟大家一起分享. 引用: 用C#来 ...

  3. C#调用非托管dll文件

    C#调用非托管dll文件 C#中如何调用动态链接库DLL C#对两种类型动态库的使用 1.托管 2.非托管 C#调用非托管dll 一.C++头文件样子 解决方案: 二.使用DLLImport类 三.二 ...

  4. C#调用非托管Dll

    最近在项目中碰到需要调用非托管C++生成的dll,下面将自己遇到的问题,以及解决的办法总结如下:   1.      问题:     我们通常去映射dll的方法是使用         public c ...

  5. java 托管 非托管_java jni调用 非托管 dll

    Step1: 编写java类,e.g.: //filename: HelloWorld.java public class HelloWorld{ public native void display ...

  6. 托管代码C#调用非托管C++ API, 封送嵌套结构体数组

    一.前言: 最近这两天由于项目需要,提供给客户的C++ 动态库需要返回自定义结构体数组,网上也查了很多资料, 推荐一本书, <精通.NET互操作:P/Invoke.C++ Interop和COM ...

  7. C#调用非托管C++DLL:直接调用法

    在实际软件开发过程中,由于公司使用了多种语言开发,在C#中可能需要实现某个功能,而该功能可能用其他语言已经实现了,那么我们可以调用其他语言写好的模块吗?还有就是,由于C#开发好的项目,我们可以利用re ...

  8. 关于Dll、Com组件、托管dll和非托管dll的理解

    Com组件和dll区别: 1.普通dll不能通过regsvr32.exe来注册,而Com组件能通过regsvr32.exe注册. 2.Com组件是微软的一个协议,满足com组件协议的dll文件就是co ...

  9. Window Services的调试和非托管dll的引用及其他一些注意问题

    一个asp.net项目,客户提出需求,需要增加即时短信提醒功能:因为项目中使用到GPRS模块做无线通讯,还可以用作发送短信,就用了这个GPRS模块发短信提醒: 这个即时短信提醒功能,计划用window ...

最新文章

  1. python计算两个向量之间的欧氏距离
  2. www万维网和HTTP协议
  3. 解决React Native unable to load script from assets index.android.bundle on windows
  4. (转)让思维活跃化的几个技巧
  5. 汇编语言:第二章 寄存器
  6. JDK源码(1)-阅读指引
  7. lua执行shell命令6_Vim执行shell命令及使用Vim批量更改文件名
  8. win10 安装visual studio 2015遇到的坑
  9. three轨迹线在mapbox地图上显示
  10. SqlServer转换为Mysql(mss2sql)
  11. 深度学习2.0-28.其他训练tricks-Early Stopping,dropout等
  12. Python 爬虫实例(10)—— 四行代码实现刷 博客园 阅读数量
  13. 无类IP地址与子网的算法
  14. Spark学习笔记(一)
  15. 18-移动端等比例缩放rem
  16. 物联网安全综述报告之感知层认证机制
  17. biostarhandboo(三)|本体论和功能分析
  18. matlab生成音阶,MATLAB 数字电子琴的功能 电子琴的每个音阶均对应一个特定频率的信号 联合开发网 - pudn.com...
  19. 请帮我查看一下2.19号邢台发往北京高铁的班次,以及各个班次的时间
  20. 高德Android 定位SDK示例

热门文章

  1. Error: opening registry key 'Software\JavaSoft\Java Runtime Environment' Error: could not find java.
  2. 汇编--在屏幕上显示彩色字体
  3. 极限环的matlab代码,matlab 数学实验 实验报告 欧拉公式 ROSSLER微分方程
  4. 电子电路设计——最小二输入与非门设计血缘检测电路
  5. 腾讯企业邮箱注册收费标准,选哪个企业邮箱更优惠
  6. 四年级计算机教学计划上册,四年级上册信息技术教学计划-(最新)
  7. 小学计算机室管理使用制度,微机室管理制度
  8. Python+Selenium挂课脚本
  9. win7 启动管理器修改默认启动项
  10. Glastopf蜜罐月报分析