1

这是我的问题。我正在尝试将 C 结构编组为 C# 结构。C 结构通过 WM_COPYDATA 消息从 C 应用程序发送到 C# 应用程序。发送和确认消息不是问题,并且工作得很好。

我在调试中运行 C 应用程序,将另一个调试器附加到 C# 应用程序并发送消息。它被正确接收和识别,但是当我尝试编组数据时, Marshal.PtrToStructure 函数似乎在执行其余部分之前退出了 switch 语句(参见代码中的标记行)。

因此不执行该过程manageComplexMessage并且数据保持原始且不可用。

这是我在 C# 中使用的 CopyDataStruct:

private struct CopyDataStruct
{ 
    public IntPtr dwData; 
    public int cbData; 
    public IntPtr lpData; 
}

这是我在 C# 中用于存储通过 WM_COPYDATA 发送的数据的结构:

private struct ComplexData
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 75)]
    public int[] integers;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 75)]
    public double[] doubles;
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.LPStr, SizeConst = 25)]
    public string[] strings;
};

处理 WM_COPYDATA 消息的方法:

protected override void WndProc(ref Message m)
{
    int id;

    base.WndProc(ref m);

    switch (m.Msg)
    {
        case WM_COPYDATA:
            CopyDataStruct rawData = (CopyDataStruct) Marshal.PtrToStructure(m.LParam, typeof(CopyDataStruct)); // This Call to PtrToStructure works perfectly fine.
            id = rawData.dwData.ToInt32();

            if (Enum.IsDefined(typeof(ComplexMessageId), id))
            {
                ComplexData data = (ComplexData) Marshal.PtrToStructure(rawData.lpData, typeof(ComplexData)); // This call makes the procedure exit.
                manageComplexMessage((ComplexMessageId) id, data);
                m.Result = (IntPtr) 1;
            }
            else
            {
                m.Result = (IntPtr) 2;
            }
            break;
    }
}

我在 C 中使用的结构将数据发送到我的 C# 应用程序:

struct ComplexData {    
    int Integers[75]; // Maximum 75 integers
    double Doubles[75]; // Maximum 75 doubles
    char Strings[25][256]; // Maximum 25 strings of a maximum length of 256 characters
};  

最后,发送消息的过程:

int SendCopydataMessage(int MessageID, struct ComplexData MessageData)
{
    COPYDATASTRUCT DataToSend;

    int result;

    DataToSend.dwData = MessageID;
    DataToSend.cbData = sizeof(MessageData);
    DataToSend.lpData = &MessageData;

    if(WindowHandle != NULL) 
    {
        result = SendMessage(WindowHandle, WM_COPYDATA, (WPARAM) ((HWND) ExecWnd), (LPARAM) ((PVOID) &DataToSend));
        if(!result) 
        {
            return MESSAGENOTPROCESSED;
        }
        if(result == 2)
        {
            return UNDEFINEDMESSAGEID;
        }
    }

    return OK;
}

我在编组字符串数组时怀疑有问题,但找不到问题。

谢谢大家的帮助!我希望有人能告诉我出了什么问题或指出我正确的方向!

编辑:经过更多测试,结构的整数部分和双精度部分工作得很好。另外,如果我发送一个字符串,它也可以工作。只有当我尝试发送一个字符串数组时它才会崩溃。然后问题出在我的 MarshalAs 字符串数组语句中,但我仍然不知道如何正确编写。

4

0 回答 0