C# 调用C++的dll 那些事

       以前历来没搞过C++,最近被安排的任务须要调用C++的接口,对于一个没用过 Dependency 的小白来讲,本来觉得像平时的Http接口那样,协议,端口必定义,方法参数一写就没事,结果踩了无数的坑。如今从0基础开始记录。A发了一个SDK文件夹过来,先无论cpp、h、lib五花八门的后缀文件,直接看文档说明,代表须要调哪些方法。网上简单的查阅下资料,发现直接引用动态库Dll 的方式是经过 DllImport去实现,命名空间为 using System.Runtime.InteropServices; c++

按照文档中方法名、参数类型的说明,写下对应代码api

[DllImport("ConX.dll", EntryPoint = "add")] public static extern int add(byte[] cfg_dir_name); //VS2017中 方法名首字母须要大写为 Add public void Test1() { int a=0; try { string str = "123"; byte[] bts = Encoding.Default.GetBytes(str); a = add(bts); } catch (Exception ex) { string strEx = ex.Message; } Console.WriteLine(a); Console.ReadLine(); }

一运行,提示 " 试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)" ,这通常是版本不匹配的缘由,肯定dll 版本为64位后,将Debug中设置为 x64 便可 (32位则设置为x86),接着运行 ,会提示 " 找不到Dll的入口点 "函数

用 DepenDency 查看下该Dll ,发现所谓的函数名变化了,并非add,变成了下图一长串的字符(CallingConvention.Cdecl 编码)学习

相关资料显示,在导出C++程序是,能够选择C方式,和C++方式,C方式不会变动函数名,C++则会,   项目右键--属性--配置属性--C/C++--高级--编译为--①C ②C++ ,固然还能够在原函数中的前面加上Extern C来限定导出后函数名不变,目前没有源码,只有dll,因此对于这种状况,只须要将变动的函数名做为入口点 赋值给 EntryPoint 便可 测试

      [DllImport("ConX.dll", EntryPoint = "?add@@YAHABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z")]编码

接着运行,这个时候 又会提示 " 请检查PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配 " , 资料显示,调用平台的默认约定 为Winapi , 而这种变动方法后的格式 " ?方法名@@YA-----------@Z " 为Cdecl 约定,因而再次更改导入dll的代码
spa

      [DllImport("ConX.dll", EntryPoint = "?add@@YAHABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z",CallingConvention=CallingConvention.Cdecl)]3d

如此折腾了一番,运行后, 若是报 " 没法加载 DLL“face_export.dll”: 找不到指定的程序 " 那就是路径有问题,通常处理方法以下调试

①直接把Dll 拷贝到 执行文件exe所在的目录下,记住经过Dependency 查看dll时,看下有没有缺失的dll ,若是没有,在将所依赖的非系统的dll 一并拷贝到 执行文件exe所在的目录下,code

②使用 Dll 的绝对路径  

③将 Dll 拷贝至系统的文件下,64位系统 对应的32位Dll则为SysWOW ,64为Dll 则为System32

      正常状况下,到这里就没有什么大问题,若是报参数问题,那就须要查阅 C++ 对应的 C# 数据类型。匹配正确便可,关键就在于我这里仍然报错,外部组件异常,外部组件异常,外部组件异常,查阅资料显示,网上没什么好的解决方案,由于这种问题的缘由五花八门,是一个很笼统的错误,但是恰恰就被我遇到了,我这边按接口中函数的申明,照葫芦画瓢写了一个C++ 的Dll,用C#调用本身写的Dll 是OK 。同事用C++调用 第三方的 Dll 也没问题(说明别人提供的Dll没问题)。这样一来就尴尬了,思路不能沉寂在这里。网上有人说是Net 版本可能不兼容,我挨个尝试一遍从3.5 切换到 4.6.1 还是外部组件异常的错误。 最后我用VS2017 打开,调试程序,仍然是外部组件异常。如今能够排除的是 不是依赖问题(报找不到Dll),不是没加载指定Dll问题, 由于不会报入口点找不到的错误,也不是参数的问题,版本的问题已经用VS2017尝试过。还会有什么方面的缘由呢?

未完待续...

      最后通过翻来覆去的测试,发现问题出在 c++ 的dll上,最后从新封装了一边dll,再次调用就没问题了,看来仍是本身学习的不够... 

相关文章
相关标签/搜索