C# 调用C++的dll 那些事
之前从来没搞过C++,最近被安排的任务需要调用C++的接口,对于一个没用过 Dependency 的小白来说,原本以为像平时的Http接口那样,协议,端口一定义,方法参数一写就没事,结果踩了无数的坑。现在从0基础开始记录。A发了一个SDK文件夹过来,先不管cpp、h、lib五花八门的后缀文件,直接看文档说明,表明需要调哪些方法。网上简单的查阅下资料,发现直接引用动态库Dll 的方式是通过 DllImport去实现,命名空间为 using System.Runtime.InteropServices;
按照文档中方法名、参数类型的说明,写下对应代码
[DllImport("ConX.dll", EntryPoint = "add")]
public static extern int add(byte[] cfg_dir_name);
//VS2017中 方法名首字母需要大写为 Add
public void Test1()
{
int a=;
try
{
string str = "";
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的代码
[DllImport("ConX.dll", EntryPoint = "?add@@YAHABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z",CallingConvention=CallingConvention.Cdecl)]
如此折腾了一番,运行后, 如果报 " 无法加载 DLL“face_export.dll”: 找不到指定的程序 " 那就是路径有问题,一般处理方法如下
①直接把Dll 拷贝到 执行文件exe所在的目录下,记住通过Dependency 查看dll时,看下有没有缺失的dll ,如果没有,在将所依赖的非系统的dll 一并拷贝到 执行文件exe所在的目录下,
②使用 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,再次调用就没问题了,看来还是自己学习的不够...
C# 调用C++的dll 那些事的更多相关文章
- 调用Interop.zkemkeeper.dll无法使用解决方案
调用Interop.zkemkeeper.dll无法使用 已经注册dll成功但是还是报错 检索 COM 类工厂中 CLSID 为 {00853A19-BD51-419B--2DABE57EB61F} ...
- c# 传递Null的string值导致的调用C++的dll报错 Attempted to read or write protected memory.
c# 调用C++的dll报错 Attempted to read or write protected memory: 原因是:c# 传递Null的string值导致的,将Null改为string ...
- Node调用C++(dll)
最近开始搞毕设了,打算用自己拿手的js来搞,但是仿佛入坑了,Node还不是很熟.总之,兵来将挡,水来土掩嘛,带着问题学习才是最高效的. 折腾1:Node 调用 C++ 刚开始,虽然我老师把dll文件给 ...
- golang调用c++的dll库文件
最近使用golang调用c++的dll库文件,简单了解了一下,特作此笔记:一.DLL 的编制与具体的编程语言及编译器无关 dll分com的dll和动态dll,Com组件dll:不管是何种语言写的都可以 ...
- vs2010下C++调用lib或dll文件
注: DLL:表示链接库,包含dll,lib文件: dll: 表示my.dll文件 lib: 表示my.lib文件 C++ 调用.lib的方法: 一: 隐式的加载时链接,有三种方法 1 设置工程的 ...
- paip.java c# .net php python调用c++ c dll so windows api 总结
paip.java c# .net php python调用c++ c dll so windows api 总结 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来 ...
- c++builder调用VC的dll以及VC调用c++builder的dll
解析__cdecl,__fastcall, __stdcall 的不同:在函数调用过程中,会使用堆栈,这三个表示不同的堆栈调用方式和释放方式. 比如说__cdecl,它是标准的c方法的堆栈调用方式,就 ...
- LabView调用C#混合模式dll
在一些特定要求下,我们的C#可能需要制作dll给LabView进行调用,并且我们不能够保证C#的程序是完全自己写而不调用第三方的dll库.很多时候我们需要使用诸如Sqlite.Net.AForge.N ...
- 关于c#调用c/c++ dll遇到的问题总结
前段时间公司做了个winform程序,需要调用c 的dll去读取卡号的程序,期间遇到些问题,下面来分享下 一.dll路径问题 相信很多开发者都会遇到这个问题,我总结了下我现在有3总方式去解决这个问题: ...
随机推荐
- python让实例作用于for循环并当做list来使用
python如果想让一个类被用于for....in 循环,类型list和tuple那样,可以实现__iter__方法. 这个方法返回一个迭代对象,python的for循环就会不断调用该迭代对象的ne ...
- windows 10 更新补丁包
http://www.catalog.update.microsoft.com/Search.aspx?q=windows%2010%20prohttp://www.catalog.update.mi ...
- Centos7 安装系统服务、开机自启动
Centos7 安装系统服务 1 编写可执行程序 * 这里可以是任意编程语言(C.C++.Java.PHP.Python.Perl ...)编写的程序: 当前假设此程序的执行目录为: /myservi ...
- hue 记录
No databases are available. Permissions could be missing. Could not start SASL: Error in sasl_client ...
- 如何免费下载付费音乐歌曲,6个网站+8个APP
现在听音乐的软件,QQ音乐,酷狗,网易云等,很多歌曲可以在线听. 但是下载某些歌曲或者在线听高品质无损的都需要付费. 这一期,给大家推荐的是免费下载付费歌曲工具,包括网站跟APP. 网站篇 1.VIP ...
- C# 不安装Oracle客户端情况下,如何连接到Oracle数据库
简介: 在我们开发应用场景经常碰到需要连接Oracle数据库,这也是相当常见的一种情况.一般.Net环境连接Oracle数据库,可以通过TNS/SQL.NET 配置文件,而 TNS 必须要 Oracl ...
- Hudson持续集成服务器的安装配置与使用
Hudson只是一个持续集成服务器(持续集成工具),要想搭建一套完整的持续集成管理平台, 还需要用到前面课程中所讲到的 SVN.Maven.Sonar等工具,按需求整合则可. 1.安装 JDK并配置 ...
- 给table加边框的样式
<style> .tb { width: 1600px; text-align: center; border-collapse: collapse; } .tb tr td { bord ...
- IkAnalyzer2012FF_u1.jar免费下载
链接:https://pan.baidu.com/s/1P_0cdRLKJO4VIUTokvTS0g 提取码:qt3w
- java学习之路--StringBuffer常见的功能和实例
---恢复内容开始--- 储存 StringBuffer append();将指定数据作为参数添加到已有数据尾处 StringBuffer insert(index,数据):可以将数据插到指定的ind ...