C#调用C++类库闪退问题记录

我们的产品上有读卡操作,所以需要和一些第三方厂商的动态库做对接。

最近再给一个项目做升级,对接电子医保。

调用对方提供的动态库时,居然直接闪退,异常都catch不到,奇葩了。。。

后来经过调查,还是动态库导入时声明的方法签名错误导致的。

错误的代码

cs 复制代码
[DllImport("SendRcv4.dll")]
public static extern string SendRcv4(string startFlag, string sendMsg, StringBuilder receivedMsg);

公司另外一个部门同事提供的代码,在.net framework 4.5及以上版本中调用直接闪退。

后来咨询了这位同事,说是要在.net framework 3.5版本调用才行。

果断写了个demo,将.net framework版本降级至4.0 调用果然就正常了。。。

但懊恼的是,我们的程序都是.net framework 4.6.2版本的,不可能为了一个第三方的类库调用,去降级啊,那成本可太大了。

经过网上查找,发现是由于入参和返回值的类型不对导致的 参考链接

正确的代码

cs 复制代码
[DllImport("SendRcv4.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr SendRcv4(IntPtr startFlag, IntPtr sendMsg, StringBuilder receivedMsg);

入参和返回值类型应该为 IntPtr

用于表示指针或句柄的平台特定类型

通常与C++类库交互时,都应该使用指针类型

存在一个隐患那就是内存释放问题,可以在DllImport时,指定由被调用方进行内存释放CallingConvention = CallingConvention.StdCall

如果不好使的话,就需要我们手动来释放内存了。

cs 复制代码
Marshal.FreeHGlobal(sendMsg);

调用代码示例

cs 复制代码
 var output = new StringBuilder(2048);
 //将字符串转换为IntPtr类型
 var startFlat = Marshal.StringToHGlobalAnsi("12345678");
 var sendMsg = Marshal.StringToHGlobalAnsi("12345678");
 SendRcv4(startFlat, sendMsg, output);

 //释放内存
 Marshal.FreeHGlobal(startFlat);
 Marshal.FreeHGlobal(sendMsg);

期间还遇到一个异常:

"System.AccessViolationException"类型的未经处理的异常在 未知模块。 中发生尝试读取或写入受保护的内存。这通常指示其他内存已损坏

这是由于没有给接收返回数据的output变量指定初始值大小导致的

cs 复制代码
//引发异常:System.AccessViolationException
var output = new StringBuilder();

//正常执行
var output = new StringBuilder(2048);

好了,到此为止。。。

相关推荐
Trouvaille ~5 分钟前
【Linux】进程信号(一):信号的快速认识与五种产生方式
linux·运维·网络·c++·操作系统·信号处理·中断
啊阿狸不会拉杆8 分钟前
《计算机操作系统》第六章-输入输出系统
java·开发语言·c++·人工智能·嵌入式硬件·os·计算机操作系统
云草桑11 分钟前
C#.net 分布式ID之雪花ID,时钟回拨是什么?怎么解决?
分布式·算法·c#·.net·雪花id
潇冉沐晴13 分钟前
div3 970个人笔记
c++·笔记·算法
云草桑13 分钟前
业务系统设计 权限系统 MAC、DAC、RBAC、ABAC 、核心概念(主体 / 客体 / 用户 - 角色 - 对象)、及数据权限
数据库·c#·权限·数据设计
王老师青少年编程16 分钟前
2023年12月GESP真题及题解(C++八级): 奖品分配
c++·题解·真题·gesp·csp·八级·奖品分配
智者知已应修善业30 分钟前
【输入字符串不用数组回车检测转换连续数字为整数】2024-10-26
c语言·c++·经验分享·笔记·算法
头发还没掉光光31 分钟前
解决TCP粘包问题,使用C++实现TCP通信的自定义协议设计
linux·网络·c++·网络协议·tcp/ip
比昨天多敲两行38 分钟前
C++ 类和对象(中)
开发语言·c++
智者知已应修善业40 分钟前
【整数各位和循环求在0-9范围】2024-10-27
c语言·c++·经验分享·笔记·算法