接收方代码 NTUser32.COPYDATASTRUCT stru = new NTUser32.COPYDATASTRUCT(); stru = (NTUser32.COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, stru.GetType()); Process p = Process.GetProcessById((int)stru.dwData); string url = Marshal.PtrToStringBSTR(stru.lpData);
发送方发送的时 txtUrl.Text="http://socansoft.com/test.html"; 接收时得到的url=“http://socansoft.com/tes” 后面被截断了,这是怎么回事?以下是声明: public const int WM_COPYDATA = 0x004A; [StructLayout(LayoutKind.Sequential)] public struct COPYDATASTRUCT { public IntPtr dwData; public int cbData; public IntPtr lpData; }
为什么要用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) 就可以了
IntPtr pData = Marshal.StringToBSTR(txtUrl.Text);
NTUser32.COPYDATASTRUCT stru = new NTUser32.COPYDATASTRUCT();
stru.dwData = new IntPtr(Process.GetCurrentProcess().Id);
stru.lpData = pData;
stru.cbData = Encoding.Unicode.GetByteCount(txtUrl.Text) + 2;
IntPtr pStru = Marshal.AllocHGlobal(Marshal.SizeOf(stru));
Marshal.StructureToPtr(stru, pStru, true);
NTUser32.SendMessage(mainHandle, NTUser32.WM_COPYDATA, IntPtr.Zero, pStru);
Marshal.FreeHGlobal(pStru);
pStru = IntPtr.Zero;
Marshal.FreeBSTR(pData);
pData = IntPtr.Zero;
stru = (NTUser32.COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, stru.GetType());
Process p = Process.GetProcessById((int)stru.dwData);
string url = Marshal.PtrToStringBSTR(stru.lpData);
接收时得到的url=“http://socansoft.com/tes”
后面被截断了,这是怎么回事?以下是声明:
public const int WM_COPYDATA = 0x004A; [StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
}
stru.cbData = Encoding.Unicode.GetByteCount(txtUrl.Text) +2;
估计是下面这个长度算法,有问题。
*****************************************************************************
签名档: http://feiyun0112.cnblogs.com/
stru.cbData = Encoding.Unicode.GetByteCount(txtUrl.Text) +20;
结果都一样,截的位置都一样,只有前24个字符
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) 就可以了
因此WM_COPYDATA可以帮你拷贝指针后面的信息,却遗漏了前面的长度信息。你可以做个试验:IntPtr ptr = Marshal.StringToBSTR("hello world"); // 11个字符,UTF16下一共是22个字节
int length = Marshal.ReadInt32(ptr - 4); //length = 22; // 隐藏的长度信息
Marshal.FreeBSTR(ptr);
我做了个实验,在发送时指针-4,长度+4发送,接收时指针+4,结果能正确解析出来,当然这只是实验,实际项目中肯定不会用BSTR发送了。结帖给分!