我有三个结构:
[StructLayout(LayoutKind.Sequential)]
internal struct COPYDATASTRUCT
{
public IntPtr dwData; // Specifies data to be passed
public int cbData; // Specifies the data size in bytes
public IntPtr lpData; // Pointer to data to be passed
}
public struct SHELLTRAYDATA
{
public UInt32 dwUnknown;
public UInt32 dwMessage;
public NID_XX nid;
}
public struct NID_XX
{
public UInt32 cbSize;
public IntPtr hWnd;
public uint uID;
public uint uFlags;
public uint uCallbackMessage;
public IntPtr hIcon;
}
在我的WndProc中,我会执行以下操作:
case WM_COPYDATA:
{
COPYDATASTRUCT cp = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
if(cp.dwData == SH_TRAY_DATA)
{
var shellTrayData = (SHELLTRAYDATA)Marshal.PtrToStructure(cp.lpData,typeof(SHELLTRAYDATA));
HandleNotification(shellTrayData);
}
}
当我的应用程序在x86上运行时,它可以正常工作。当我在x64上运行它时,我没有得到一个hIcon,而且hWnd无效。当我将应用程序定位到x86并在x64上运行时,它工作正常。我知道问题在于编组。我是否必须手动编组结构?需要帮助。我希望x64和x86都具有相同的结构
编辑:
非托管结构如下:
typedef struct tagCOPYDATASTRUCT
{
ULONG_PTR dwData;
DWORD cbData;
_Field_size_bytes_(cbData) PVOID lpData;
} COPYDATASTRUCT, *PCOPYDATASTRUCT;
// data sent by shell via Shell_NotifyIcon
typedef struct _SHELLTRAYDATA
{
DWORD dwUnknown;
DWORD dwMessage;
NID_XX nid;
} *PSHELLTRAYDATA;
// sub structure common to all others
typedef struct
{
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
} NID_XX, *PNID_XX;
typedef const NID_XX * PCNID_XX;
编辑: 结构的大小如下:
未管理:
托管:
双方都是一样的。
答案 0 :(得分:1)
这些结构因不同的架构而异。 IntPtr
值为32位宽,或64位宽,具体取决于架构。这对成员的规模有明显的影响,也许对协调的后果不太明显。
无论架构如何,都无法使用相同的结构。您需要了解这两个过程的架构。无论何时发送方和接收方都没有相同的架构,那么您就遇到了麻烦。
您可以使用C#long
代替IntPtr
选择固定布局。 HWND
和HICON
等类型始终适合C#long
。虽然要注意只在特定过程中有意义的句柄类型。例如,一旦将HICON
值发送到其他进程,WM_COPYDATA
值就没有意义。
我认为我会序列化,而不是使用固定的布局结构。例如,序列化您要发送给JSON的数据。这可以很容易地打包成一个字符串并通过{{1}}发送。
答案 1 :(得分:0)
由于Handles在64位构建上是64位,而我们接收的结构仍然包含32位。为hIcon和hWnd将IntPtr更改为Uint32就可以了。现在这个结构适用于x64和x86架构。我一直都知道JSON的序列化肯定会偏离我的要求。感谢您的帮助。