日期:2014-05-16  浏览次数:21549 次

Marshal.StringToBSTR 发送消息后,接收时不完整?
我用WM_COPYDATA发送消息到另一个进程,另一个进程接收到后反向用Marshal.PtrToStringBSTR解析,字符被截断了,这是怎么回事?
------解决方案--------------------
为什么要用bstr,
msdn 上已经讲明
A BSTR is a composite data type that consists of a length prefix, a data string, and a terminator. The following table describes these components
A BSTR is a pointer. The pointer points to the first character of the data string, not to the length prefix.
所以你直接用
   stru.cbData = Encoding.Unicode.GetByteCount(txtUrl.Text) + 2; 是不一定对的
最好用Marshal.StringToCoTaskMemAuto 就可以了
长度用
Encoding.Default.GetByteCount(txtUrl.Text)  就可以了
------解决方案--------------------
你可以在调试一下把 Marshal.PtrToStringBSTR获得的intptr 所指向的内存是否与c++中的bstr一样指向的是字符串的第一个字节,没有包括他的长度前缀,如果是的话,接受方肯定不会得到正确的代码
------解决方案--------------------
建议你不要用BSTR。

BSTR带有长度信息,但是长度信息被隐藏在指针的前面。
因此WM_COPYDATA可以帮你拷贝指针后面的信息,却遗漏了前面的长度信息

你可以做个试验:

IntPtr ptr = Marshal.StringToBSTR("hello world");     // 11个字符,UTF16下一共是22个字节
int length = Marshal.ReadInt32(ptr - 4); //length = 22;  // 隐藏的长度信息
Marshal.FreeBSTR(ptr);