WM_COPYDATA 消息可以传送大量数据,其方法有很多文章介绍,此处不赘述。
不过现在64位系统越来越多,传统应用经常是32位系统的,如果处理不好,经常会遇到消息无法传送,或者消息解析错误等问题。
首先看看COPYDATASTRUCT的定义,分析问题原因:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms649010%28v=vs.85%29.aspx 这是MSDN的定义页面。
typedef struct tagCOPYDATASTRUCT { ULONG_PTR dwData; DWORD cbData; PVOID lpData; } COPYDATASTRUCT, *PCOPYDATASTRUCT;可以看到,其中的三个成员,类型各不相同,但在32位系统中,这三个成员都是4个字节(可以搜索一下ULONG_PTR,DWORD,PVOID的定义)。
根据有些文章的介绍,在C#中,该结构定位被写为(当然还有别的写法,但只要里边有IntPtr,或者其他类型的指针,就会有同样的问题):
[StructLayout(LayoutKind.Sequential)]
struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
}
其中 int 的确是32位的,而IntPtr就会根据不同的平台而变化。如果您的C#项目属性中, “生成”属性中,“目标平台”是 Any CPU的话,那么在64位平台上运行时,dwData和lpData就会被解释成64位的,从而与32位的传统程序将不再兼容。
知道了原因就好办了:
- 可以把c#的目标平台设置为 x86系统,这样C#应用就会被当成32为应用,保持 COPYDATASTRUCT 结构的兼容性。
- 或者在C#中 强制COPYDATASTRUCT 结构的每个成员都是Int32,引用的时候做一定的类型转换,也能和32位程序交互。不过这时要保证 lpData的指针的正确性。万一lpData指向的数据区指针长度超过了32位,结果将不可预知。本人实践中未遇到过这种情况,但不能保证不会发生。