C#调用C/C++动态库,关于参数char*和char**的处理
问题:C函数经过C#封装后,调用结果是参数中的char*无效。
然而再C中调用结果是对的,代码如下:
typedef const void *sntl_lg_vendor_code_t;
char* current_state;
char* temp2;
char* decode_state = NULL;
status = sntl_lg_decode_current_state(handle, (sntl_lg_vendor_code_t)temp2, current_state, &decode_state);
随初步定位为char*不能直接用string代替。
然后,在C#封装的函数中,将所有的string替换成byte[]。返回的status结果是对了,但是ref byte[]的传出参数值不对。只传出了一个地址。
网上有人认为char**应该用IntPtr[]替换,但是结果和byte[]一样还是不对,只传出了一个地址。随后查了CharSet的作用,然后将CharSet改为了CharSet = CcharharSet.Ansi,传出结果正确了。此时将所有的byte[]又改回string,结果仍然正确。
关于CharSet以下是官方解释:
//
// 摘要:
// 决定封送字符串应使用的字符集。
[ComVisible(true)]
public enum CharSet
{
//
// 摘要:
// 此值已过时,并具有相同的行为 System.Runtime.InteropServices.CharSet.Ansi。
None = 1,
//
// 摘要:
// 为多字节字符字符串的封送字符串。
Ansi = 2,
//
// 摘要:
// 封送为 Unicode 双字节字符的字符串。
Unicode = 3,
//
// 摘要:
// 自动封送目标操作系统为适当的字符串。 默认值是 System.Runtime.InteropServices.CharSet.Unicode 有关 Windows
// NT、 Windows 2000、 Windows XP 和 Windows Server 2003 家族中; 默认值是 System.Runtime.InteropServices.CharSet.Ansi
// 在 Windows 98 和 Windows me。 虽然公共语言运行时默认设置是 System.Runtime.InteropServices.CharSet.Auto,
// ,语言可重写此默认值。 例如,默认情况下 C# 标记的所有方法和类型作为 System.Runtime.InteropServices.CharSet.Ansi。
Auto = 4
}
结论:C中的函数参数char*和char**,在用C#封装时是可以用string的。但是注意要将CharSet改为了CharSet = CcharharSet.Ansi。默认的CharSet = CharSet.Auto是会出错的。