一次WPF(C#)调用C++dll库的学习记录

4 篇文章 1 订阅


本文开发过程,对接硬件开发,但是只有Demo软件,以及dll函数说明chm文档,没有Demo代码,chm文档里函数太多,且杂乱无章,重复!

确定C++编写的dll库在C#中的类型对应关系

以下是本次学习过程中使用到的一些的对应关系:

C /C++语言类型C# 数据类型
char * 变量名StringBuilder 变量名
intint
longint
unsigned char 变量名byte 变量名
unsigned char * 变量名ref byte 变量名
HANDLESystem.IntPtr
unsigned short 变量名Int16 变量名
short 变量名Int16 变量名

更详细对照关系参见该文章

函数举例,比如:

  • 这是一个初始化接口函数
    HANDLE USER_API PrinterInit ( short port, int baud )

转成C#后

 [DllImport("Demo.dll")]
 public static extern IntPtr PrinterInit  (Int16 port, int baud);
  • 打印机参数获取
    int __stdcall PrinterCheck ( unsigned char * FontSize, unsigned char* Alignment, unsigned char* LeftMargin, unsigned char* RightMargin, unsigned char* RowPitch, unsigned char* PrintOutRate )
[DllImport("Demo.dll")]
public static extern int PrinterCheck(ref byte FontSize, ref byte Alignment, 
ref byte LeftMargin,ref byte RightMargin, ref byte RowPitch, ref byte PrintOutRate);
  • 打印机参数设置
    int __stdcall PrinterSet(unsigned char FontSize, unsigned char Alignment,unsigned char LeftMargin, unsigned char RightMargin,unsigned char RowPitch,unsigned char PrintOutRate)
 [DllImport("Demo.dll")]
 public static extern int PrinterSet(byte FontSize, byte Alignment, byte LeftMargin, 
 byte RightMargin, byte RowPitch, byte PrintOutRate);
  • 读取身份证
    long __stdcall ReadIdentityCard ( int iType, char* pOutInfo,int iCreatPhoto = 0 )
[DllImport("Demo.dll", CallingConvention = CallingConvention.Winapi)]
public static extern int ReadIdentityCard (int iType, StringBuilder pOutInfo, int iCreatPhoto);

以上列举的类型对应转换关系,是测试可用的。

确定函数调用

如果开发过程中,第三方提供了SDK和Demo代码,那上面的转换过程就没必要了,现在的前提就是,第三方只提供Demo软件,不给Demo代码,这就麻烦了
c++写的程序,又不能像Androud那样反编译,这时了解到可以通过 ollydbg 软件来得知程序调用了哪些函数,在这里插入图片描述
如上图,可以知道 里面的函数对应哪个操作

知道函数之后,就去函数说明文档里找对应函数,然后按照第一步的对应关系便可转成C#能调用的方法了

一定要注意关系转换正确,很多崩溃错误都是由于这个引起的

问题记录:

  • 1、在读取身份信息的时候,ReadIdentityCard (int iType, StringBuilder pOutInfo, int iCreatPhoto);要传入StringBuilder 参数
    ,开始是这样的
string result = "";
result = result.PadLeft(1024 * 4);
StringBuilder sb = new StringBuilder(result);
ReadIdentityCard(1,sb,0);

但是这种方式经常会崩溃,提示 System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
折腾半天之后 改成 StringBuilder sb = new StringBuilder(1024*4); 就可以了,还不明白为什么

  • 2、异常崩溃 程序捕获不到的那种。。
    身份证 与 打印机不能同时使用,因为是同一传输线

2022-07-15 记录

调用打印机厂商提供的dll库来监测打印机状态,本来按照约定的函数调用,结果提示 【无法在DLL "xxxx.dll"中找到名为“xxxx”的入口函数】,按理正常情况是不会提示这个错误的,就猜测是不是定义函数有误。
这里度娘又告诉我,可以使用windows系统里的工具来查看dll里定义的函数情况。
我使用的是win10下VS2019,使用everything搜 【dumpbin.exe】
如果存在的话,打开路径,然后在该路径下使用cmd命令 【dumpbin.exe /EXPORTS “xxx.dll”】
如下图。
红框里才是dll库里实际的方法函数名,和文档约定的是不一样的,导致调用失败提示 【无法在DLL "xxxx.dll"中找到名为“xxxx”的入口函数】,是真的坑!

![在这里插入图片描述](https://img-blog.csdnimg.cn/76cf7e9297b24eafac9607299b1d26bb.png

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值