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; 
}

これは、WM_COPYDATA を介して送信されたデータを格納するために C# で使用する構造体です。

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