关于c#调用c/c++ dll遇到的问题总结
前段时间公司做了个winform程序,需要调用c 的dll去读取卡号的程序,期间遇到些问题,下面来分享下
一、dll路径问题
相信很多开发者都会遇到这个问题,我总结了下我现在有3总方式去解决这个问题;
1.直接放在bin下面,跟exe文件在同一文件夹下,
ps:调试代码的时候,如果是debug模式的话,就放bin/debug下,同理release 模式就放bin/debug下;如果这种方式不行的话,就试试第二种方式。
2.放在C:\Windows\System32下;
3.如果以上方式都不行的话就,那就只能写物理路径了。例
[System.Runtime.InteropServices.DllImportAttribute(@"E:\Source\GPTagReaderDll", EntryPoint = "OpenPort", CallingConvention = CallingConvention.Cdecl)]
[return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
public static extern bool OpenPort(string pPortname, uint dBaud);
该种方式只适合调一个dll的方式,如果调用的这个dll依赖于其他的dll的话这种方式是行不通的;这种方式还有局限性,如果发布出去,你得要求别人的机子上这个物理路径下必须有这个文件,但是 这个太不现实了
除这3种方式外,还听说过写到环境变量里,不过这种方式没试过,就不在此提了。
二、类型转换的问题
下面是c的结构体:
typedef struct
{
unsigned char DeviceIdentify[30];//Greenpow Usb IC card reader
unsigned short res;
}FindDeviceAck_Struct;
我们需要把它转换成c#的结构体:
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential,
CharSet = System.Runtime.InteropServices.CharSet.Ansi,Pack =1)]
public struct FindDeviceAck_Struct
{ /// unsigned char[30]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr,
SizeConst = 30)]
public string DeviceIdentify; /// unsigned short
public ushort res;
}
c# 跟c/c++类型的对应方式,可参考http://www.cnblogs.com/ausoldier/archive/2007/12/07/986141.html;
我这里DeviceIdentify用String接收,但是出现了乱码,后来改成了
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential,
CharSet = System.Runtime.InteropServices.CharSet.Ansi,Pack =1)]
public struct FindDeviceAck_Struct
{ /// unsigned char[30]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray,
SizeConst = 30)]
public byte[] DeviceIdentify; /// unsigned short
public ushort res;
}
string 对应的是ByValTStr,byte[] 对应的是ByValArray,sizeconst指的是大小,pack=1表示按1字节对齐
三、调用c里的方法
c里的方法是BOOL FindDevice(FindDeviceAck_Struct &finddeviceack);
刚开始我直接这样写,
[System.Runtime.InteropServices.DllImportAttribute("GPTagReaderDll", EntryPoint = "FindDevice", CallingConvention = CallingConvention.Cdecl)]
public static extern bool FindDevice(FindDeviceAck_Struct finddeviceack);
调用的时候
FindDeviceAck_Struct findDeviceAck=new FindDeviceAck_Struct();
var result= NativeMethods.FindDevice(findDeviceAck);
结果报了下面这个错误:尝试读取或写入受保护的程序。通常指示其他内存已经存在。

后来同事提醒才注意到BOOL FindDevice(FindDeviceAck_Struct &finddeviceack)参数&finddeviceack 有个'&'。
经改成
[System.Runtime.InteropServices.DllImportAttribute("GPTagReaderDll", EntryPoint = "FindDevice", CallingConvention = CallingConvention.Cdecl)]
public static extern bool FindDevice(ref FindDeviceAck_Struct finddeviceack);
这样就调用成功了
关于c#调用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++的DLL搜集整理的所有数据类型转换方式
//C#调用C++的DLL搜集整理的所有数据类型转换方式,可能会有重复或者多种方案,自己多测试 //c++:HANDLE(void *) ---- c#:System.IntPtr //c++:Byt ...
随机推荐
- 第一百九十六天 how can I 坚持
老妈邮的咸菜到了,美味啊,买不到,哈哈. 以后要勤给鱼换水啊,10天不换,水都臭了,拒绝懒惰. 明天要回济南了,刘松结婚,估计又没法发博客了. 两条鱼,一条罗娜,一条我,哈哈. 睡觉.
- [翻译]创建ASP.NET WebApi RESTful 服务(8)
本章讨论创建安全的WebApi服务,到目前为止,我们实现的API都是基于未加密的HTTP协议,大家都知道在Web中传递身份信息必须通过HTTPS,接下来我们来实现这一过程. 使用HTTPS 其实可以通 ...
- Javascript函数柯里化(curry)
函数柯里化currying,是函数式编程非常重要的一个标志.它的实现需要满足以下条件,首先就是函数可以作为参数进行传递,然后就是函数可以作为返回值return出去.我们依靠这个特性编写很多优雅酷炫的代 ...
- C#中位、字节等知识
本文介绍C#中位.字节等知识. 1. 位(bit) 位(bit)有叫做比特,指二进制中的一位,是二进制的最小信息单位. bit也被称作小b,用b表示. 2. 字节(bytes) 8位表示一个字节. 由 ...
- 根据路径获得文件名以及Aspose.Cells.dll操作excel 以及使用iTextSharp.text.pdf.PdfReader.dll对PDF的操作
string result = Regex.Match(str,@"[^\\]+$").Value;//正则表达式 this.listBox1.Items.Add(Path.Get ...
- POJ 3254 Corn Fields (状压dp)
题目链接:http://poj.org/problem?id=3254 给你n*m的菜地,其中1是可以种菜的,而菜与菜之间不能相邻.问有多少种情况. 状压dp入门题,将可以种菜的状态用一个数的二进制表 ...
- Web Service实现分布式服务的基本原理
简单的说, 就是客户端根据WSDL 生成 SOAP 的请求消息, 通过 HTTP 传输方式(也可以是其它传输方式, 如 FTP 或STMP 等,目前 HTTP 传输方式已经成为 J2EE Web Se ...
- JSP文件下载时文件名在ie和firefox下面文件名不一致极其超链接中文乱码的问题的改进
response.setContentType("application/octet-stream;charset=UTF-8"); fileName=java.net.URLEn ...
- visual studio 设计器上出现蓝色的点和箭头
visual studio 设计器上出现蓝色的点和箭头: 突然发现打开visual studio 的时候出现了很多蓝色的点和箭头,解决办法是:按组合快捷键 Ctrl+R,Ctrl+W 或 Ctrl+E ...
- 【原创】[PS技巧]如何制作翘角纸条的阴影效果
(从已经死了一次又一次终于挂掉的百度空间人工抢救出来的,发表日期 2014-05-19) 在网页设计中经常会用到翘角纸条的效果.如:百度空间首页: pic.1 下面我详细讲解一下这个效果使用PS如何制 ...