从 WM_COPYDATA 消息编组结构
Posted
技术标签:
【中文标题】从 WM_COPYDATA 消息编组结构【英文标题】:Marshalling structs from WM_COPYDATA messages 【发布时间】:2009-10-28 15:13:06 【问题描述】:我正在尝试让 C# WPF 应用程序与另一个使用 WM_COPYDATA 用 C 编写的应用程序进行通信。 C 应用程序正在尝试发送如下结构:
typedef struct
int x;
int y;
char str[40];
double d;
char c;
DATASTRUCT;
在我的 C# 应用程序中,我定义了一个结构如下:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct DATASTRUCT
public int x;
public int y;
[MarshalAs(UnmanagedType.LPStr, SizeConst=40)]
public string s;
public double d;
public char c;
;
接收WM_COPYDATA消息的代码如下:
private void Window_Loaded(object sender, RoutedEventArgs e)
hwndSource = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
hwndSource.AddHook(new HwndSourceHook(WndProc));
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
if (msg == 0x4A)
DATASTRUCT data = (DATASTRUCT)Marshal.PtrToStructure(lParam, typeof(DATASTRUCT));
this.updateText(data);
handled = true;
return (IntPtr)0;
我正在接收来自 C 应用程序的消息,但结构中的所有数据都是乱码。在此之前,我能够手动从 lParam 指针中提取一个字节数组,然后使用 System.BitConverter 和 System.Text.Encoding.ACII 来解释字节数组,效果很好。但现在我正试图以一种更清洁的方式来做这件事,但它不起作用。
【问题讨论】:
【参考方案1】:在寻找这个问题的答案很长时间之后,我意识到我错过了一个非常重要的步骤。我觉得自己像个白痴,但这是我自己问题的答案。
C# 结构应如下所示:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public unsafe struct DataStruct
public int x;
public int y;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=40)]
public string s;
public double d;
public char c;
;
并且必须定义另一个结构来接收 WM_COPYDATA 信息。它看起来像这样:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public unsafe struct CopyDataStruct
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
WndProc 方法应该改成这样:
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
if (msg == 0x4A)
CopyDataStruct cps = (CopyDataStruct)Marshal.PtrToStructure(lParam, typeof(CopyDataStruct));
DataStruct data = (DataStruct)Marshal.PtrToStructure(cps.lpData, typeof(DataStruct));
updateText(data);
handled = true;
return (IntPtr)0;
我在以前的工作解决方案中使用了 CopyDataStruct,但我忘记在较新的版本中使用它。
【讨论】:
嗨,我也有同样的问题。你能分享整个代码吗?我想我要么是 DllImport 有问题,要么是我发送消息的代码错误。谢谢!【参考方案2】:部分问题在于 str 成员需要是 ByValTStr 而不是 LPSTR,因为它是内联字符串数组。试试下面的定义
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct DATASTRUCT
public int x;
public int y;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=40)]
public string s;
public double d;
public char c;
;
【讨论】:
以上是关于从 WM_COPYDATA 消息编组结构的主要内容,如果未能解决你的问题,请参考以下文章
在 WPF 或控制台 C# 应用程序中接收 WM_COPYDATA 结构