刚才遇到了关于C#使用外部DLL函数上的char*的问题。

有个网友在群中说:“问一个问题,vc写的dll返回值为char *,c#中如何定义,我定义了string,要出错的。”
有个网友建议他用unsafe,而后来他说他解决了,他的代码如下:

None.gif  [ StructLayout( LayoutKind.Sequential, CharSet= CharSet.Ansi ) ]
None.gif   
public struct   KeyBuf
ExpandedBlockStart.gifContractedBlock.gif  
dot.gif {
InBlock.gif            [ MarshalAs( UnmanagedType.ByValTStr, SizeConst
=256 )] 
InBlock.gif            
public string c;
ExpandedBlockEnd.gif  }
 

他说这样就可以解决了,但后来,他又问,为什么非要用结构?
我也不清楚,希望有朋友可以指出一下。

后来,我试了一下:
None.gif   [MarshalAs(UnmanagedType.LPArray)] 
None.gif  
public byte[] c;

但有一些问题,后来,用了:
None.gif [MarshalAs(UnmanagedType.LPArray)] 
None.gif
public byte[] c=new byte[256];

为byte弄了一个缓冲区,成功了。

但又遇到一个问题,用Conver不能直接转换数符为string,所以改用了System.Text.Encoding才解决了问题。

经查MSDN资料发现UnmanagedType 枚举描述:
ByValTStr
用于在结构中出现的内联定长字符数组。与 ByValTStr 一起使用的字符类型由应用于包含结构的 System.Runtime.InteropServices.StructLayoutAttribute 的 System.Runtime.InteropServices.CharSet 参数确定。应始终使用 MarshalAsAttribute.SizeConst 字段来指示数组的大小。 .NET Framework 的 ByValTStr 类型的行为类似于结构中的 C 样式、固定大小的字符串(例如,char s[5])。托管代码中的行为与 Microsoft Visual Basic 6.0 中的行为不同,后者不是空终止(例如,MyString As String * 5)。

LPArray

指向 C 样式数组的第一个元素的指针。当从托管到非托管进行封送处理时,该数组的长度由托管数组的长度确定。当从非托管到托管进行封送处理时,将根据 MarshalAsAttribute.SizeConst 和 MarshalAsAttribute.SizeParamIndex 字段确定该数组的长度,当需要区分字符串类型时,还可以后跟数组中元素的非托管类型。

也就是说ByValStr仅适合用于定长的字符串,而LPArray才用于不定长的字串。
看见国外有用StringBulider的解决方案,是String到Char *的映射的,还没试过行不行,具体可以看这里

转载于:https://www.cnblogs.com/William_Fire/archive/2004/07/31/28950.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值