前段时间公司做了个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遇到的问题总结的更多相关文章

  1. 调用Interop.zkemkeeper.dll无法使用解决方案

    调用Interop.zkemkeeper.dll无法使用 已经注册dll成功但是还是报错 检索 COM 类工厂中 CLSID 为 {00853A19-BD51-419B--2DABE57EB61F} ...

  2. 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 ...

  3. Node调用C++(dll)

    最近开始搞毕设了,打算用自己拿手的js来搞,但是仿佛入坑了,Node还不是很熟.总之,兵来将挡,水来土掩嘛,带着问题学习才是最高效的. 折腾1:Node 调用 C++ 刚开始,虽然我老师把dll文件给 ...

  4. golang调用c++的dll库文件

    最近使用golang调用c++的dll库文件,简单了解了一下,特作此笔记:一.DLL 的编制与具体的编程语言及编译器无关 dll分com的dll和动态dll,Com组件dll:不管是何种语言写的都可以 ...

  5. vs2010下C++调用lib或dll文件

    注: DLL:表示链接库,包含dll,lib文件: dll: 表示my.dll文件 lib: 表示my.lib文件 C++ 调用.lib的方法: 一: 隐式的加载时链接,有三种方法 1  设置工程的 ...

  6. 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 来 ...

  7. c++builder调用VC的dll以及VC调用c++builder的dll

    解析__cdecl,__fastcall, __stdcall 的不同:在函数调用过程中,会使用堆栈,这三个表示不同的堆栈调用方式和释放方式. 比如说__cdecl,它是标准的c方法的堆栈调用方式,就 ...

  8. LabView调用C#混合模式dll

    在一些特定要求下,我们的C#可能需要制作dll给LabView进行调用,并且我们不能够保证C#的程序是完全自己写而不调用第三方的dll库.很多时候我们需要使用诸如Sqlite.Net.AForge.N ...

  9. C#调用C++的DLL搜集整理的所有数据类型转换方式

    //C#调用C++的DLL搜集整理的所有数据类型转换方式,可能会有重复或者多种方案,自己多测试 //c++:HANDLE(void *) ---- c#:System.IntPtr //c++:Byt ...

随机推荐

  1. (mac)Android Studio安装以及Fetching android sdk component information超时的解决方案

    解决Mac下面Fetching android sdk component information加载过久问题, 关于windows中可以参考前面一篇文章 关于安装和下载可以百度一下地址.安装完成后, ...

  2. 咏南多层开发框架支持最新的DELPHI 10 SEATTLE

    购买了咏南多层开发框架的老用户如有需要提供免费升级. 中间件

  3. json的一些问题

    使用json不仅可以这么写,{"ARCHIVAL_CODE":"String","TDQLR":"String"} 还可 ...

  4. NS_ENUM & NS_OPTIONS

    When everything is an object, nothing is. So, there are a few ways you could parse that, but for the ...

  5. 一个人写的操作系统 - Sparrow OS

    一个人写的操作系统 - Sparrow OS 自己写一个操作系统,这是在过去的几年里我一直为之努力的目标,现在终于完成了. 缘起 自己动手写操作系统的动机最初来自于学习Linux遇到的困难. 我是一个 ...

  6. [Sparrow OS 设计文档连载(一)] Introduction

  7. iisapp 命令 弹出 iisschlp.wsc [88,25] 属性值无效 progid

    iisapp 命令 弹出 iisschlp.wsc [88,25] 属性值无效 progid 在执行iisapp.vbs时,可能会提示如下错误:Windows Script Component - f ...

  8. 用jQuery解决弹出层的问题

    在BS 项目中 经常需要用到这种弹出层.做这种弹出层一般都会遇到下面几个问题:0,弹出层必须定义在input的下边显示.1,点击input弹出div层.2,点击div层外面任何地方,关闭div层.3, ...

  9. Hadoop on Mac with IntelliJ IDEA - 8 单表关联NullPointerException

    简化陆喜恒. Hadoop实战(第2版)5.4单表关联的代码时遇到空指向异常,经分析是逻辑问题,在此做个记录. 环境:Mac OS X 10.9.5, IntelliJ IDEA 13.1.5, Ha ...

  10. JDBC概述以及几种驱动程序

    JDBC(Java DataBase Connectivity,数据库连接)是用来执行SQL的Java API.开发人员可以使用这些标准API来连接和操作数据库 JDBC是Java的规范,考虑到规范的 ...