C#如何通过DllImport从非托管DLL中获取AnsiString字符串数组
问题原因分析
- 导入声明的字符集配置错误:官方文档明确输入参数是AnsiString类型,你编写的DllImport里CharSet设为了Unicode,导致传入的字符串参数编码不匹配,DLL接收到的输入本身就是错误的,返回结果自然异常。
- 返回值解析逻辑错误:函数返回的
AnsiString*是指向字符串指针数组的首地址,不是直接指向单个字符串的指针。你之前直接对返回的首地址调用PtrToStringAnsi/PtrToStringUni,相当于把数组里的指针值当成了字符串内容解析,当然会得到乱码。
修复方案
1. 修正DllImport声明
把CharSet改为Ansi匹配输入参数的编码要求:
[DllImport("PS3_DLL.dll", EntryPoint = "Request_the_Value_of_ICT_multi_Currency_Bill_Validator", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] private static extern IntPtr Request_the_Value_of_ICT_multi_Currency_Bill_Validator(string strCurrency);
2. 正确解析返回的字符串数组
按照官方文档说明,返回的数组共有20个元素(索引0到19),先把返回的首地址拷贝为IntPtr数组,再遍历每个指针转成Ansi字符串即可:
IntPtr pData = Request_the_Value_of_ICT_multi_Currency_Bill_Validator("AUD"); // 按官方文档数组长度为20,可根据实际返回结果调整长度 IntPtr[] ptrArray = new IntPtr[20]; Marshal.Copy(pData, ptrArray, 0, ptrArray.Length); string[] result = new string[20]; for (int i = 0; i < 20; i++) { result[i] = Marshal.PtrToStringAnsi(ptrArray[i]); }
注意事项
- 确认非托管DLL的内存释放规则:如果返回的字符串数组是DLL内部动态分配的内存,需要查阅官方文档确认是否需要调用对应的释放函数回收内存,避免出现内存泄漏。
- 数组长度要和DLL实际返回的长度匹配,避免内存越界读取。
内容的提问来源于stack exchange,提问作者Joman Rey
相关产品推荐
相关产品推荐

