C#调用Delphi DLL获取字符串(C# IntPtr 与 string互转 )
前因后果
调用一门锁的dll实现读取酒店IC卡数据,直接用Readme里的方法出错。
函数声明:
一、读卡函数
************************ Delphi 调用 *************************
* function DLL_Read:PChar;
external 'AnLock_2012.dll'; stdcall;
**************************************************************
*
************************* VB 调用 ****************************
* Private Declare Function DLL_Read Lib "AnLock_2012.dll" As String
*
**************************************************************
*
************************* PB 调用 ****************************
* Function String DLL_Read Library "AnLock_2012.dll";
**************************************************************
*
************************* C# 调用 ****************************
* [DllImport("AnLock_2012.dll", EntryPoint = "DLL_Read", CharSet = CharSet.None, SetLastError = false)]
* public static extern String DLL_Read;
**************************************************************
**************************************************************
返回字符串格式说明:
|CardNo 卡号
|CardType 卡片类型
|Building 楼栋号
|Floor 楼层号
|RC 锁内号(门锁内定义的房间编号,与房间号一一对应)
|RN 房间号(若无关联房间号,则为锁内号)
|StartDT 入住时间
|EndDT 欲离时间
|OpenUnLock 可开反锁
|AlwaysOpen 常开门
|EndOldCard 终止前卡
**************************************************************
读卡返回值例子
例1: |CardNo3354970509|CardTypeGuestCard|RC1101|RN1101|StartDT20131209_00:00|EndDT20131214_00:00
以上读卡信息表示:
卡号为3354970509,卡片类型为GuestCard(宾客卡)
|RC1101|RN1101当不在门锁系统内锁内号与房号相等,一般只需处理|RC1101(锁内号)
|StartDT20131209_00:00|EndDT20131214_00:00 表示入住时间为2013年12月09号0点、退房时间2013年12月14号0点
1 2 | [DllImport( "ANLOCK_2012.dll" , EntryPoint = "DLL_Read" , CharSet = CharSet.None, SetLastError = false )] public static extern string DLL_Read(); |
分析和解决办法
delphi里导出string估计是使用的pchar,那么C#里面调用时取到是内存地址的句柄才对,试试用IntPtr来接收。一测试OK了。其实问题就是一句话:C# IntPtr与string的互转。
另外64位操作系统也会报错,解决办法就是编译生成的时候不要用AnyCPU,用x86。
正确的姿势:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | [DllImport( "ANLOCK_2012.dll" , EntryPoint = "DLL_Read" , CharSet = CharSet.None, SetLastError = false )] public static extern IntPtr DLL_Read(); public Form1() { InitializeComponent(); } private void button1_Click( object sender, EventArgs e) { var temp = DLL_Read(); string ss = Marshal.PtrToStringAnsi(temp); textBox1.Text = ss; //最后释放掉 //Marshal.FreeHGlobal(temp); } |
作者:数据酷软件
出处:https://www.cnblogs.com/datacool/p/datacool_2018_CSharp_Delphi.html
关于作者:20年编程从业经验,持续关注MES/ERP/POS/WMS/工业自动化
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明。
联系方式: qq:71008973;wx:6857740733
基于人脸识别的考勤系统 地址: https://gitee.com/afeng124/viewface_attendance_ext
自己开发安卓应用框架 地址: https://gitee.com/afeng124/android-app-frame
WPOS(warehouse+pos) 后台演示地址: http://47.239.106.75:8080/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构