1

あるアプリケーションから別のアプリケーションに double 配列を送信する際に問題がありました (両方とも c#)。

私はこのようにフォーマットしようとしますCopyData Struct

    [StructLayout(LayoutKind.Sequential)]
    public struct CopyDataStruct
    {
        public IntPtr dwData;
        public int cbData;
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.R8)]
        public double[] lpData;
    }

ではSender Application、次のように構造体を埋めます。

            double[] a = new double[2] { 1.0, 2.0 };
            int size = Marshal.SizeOf(typeof(double)) * a.Count();

            CopyDataStruct copyDataStruct;
            copyDataStruct.dwData = IntPtr.Zero;
            copyDataStruct.lpData = a;
            copyDataStruct.cbData = size;

            int result = SendMessage(hWnd, WM_COPYDATA, 0, ref copyDataStruct);

で、私はこれReceiver Applicationを試します:

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        switch (msg)
        {
            case (int)WINMESSAGES.WM_COPYDATA:
                CopyDataStruct cp = (CopyDataStruct)Marshal.PtrToStructure(lParam, typeof(CopyDataStruct));

                break;
        }

        return IntPtr.Zero;
    }

しかしcp.lpDat、価値がありnullます。間違って送信したのか、間違って受信したのかわかりません。助けてください、ありがとう。

4

1 に答える 1

0

ネイティブ メモリを使用する必要があります。そのようにC# を渡しdouble[]てもうまくいきません。ガベージコレクションされます(C#では割り当てられていません-スタックにあるだけです)。unsafe/fixed キーワードを使用してオブジェクトを固定するか、 を使用できますAllocHGlobal

これは私がインターネットから切り取ったコードです。送信部分を示します:

    // Marshal the managed struct to a native block of memory.
    var myStruct = new double[2] { 1.0, 2.0 };
    int myStructSize = Marshal.SizeOf(myStruct); 
    IntPtr pMyStruct = Marshal.AllocHGlobal(myStructSize);
    try
    {
        Marshal.StructureToPtr(myStruct, pMyStruct, true);

        COPYDATASTRUCT cds = new COPYDATASTRUCT();
        cds.cbData = myStructSize;
        cds.lpData = pMyStruct;

        // Send the COPYDATASTRUCT struct through the WM_COPYDATA message to 
        // the receiving window. (The application must use SendMessage, 
        // instead of PostMessage to send WM_COPYDATA because the receiving 
        // application must accept while it is guaranteed to be valid.)
        NativeMethod.SendMessage(hTargetWnd, WM_COPYDATA, this.Handle, ref cds);

        int result = Marshal.GetLastWin32Error();
        if (result != 0)
        {
            MessageBox.Show(String.Format(
                "SendMessage(WM_COPYDATA) failed w/err 0x{0:X}", result));
        }
    }
    finally
    {
        Marshal.FreeHGlobal(pMyStruct);
    }

撮影: http://code.msdn.microsoft.com/windowsdesktop/CSReceiveWMCOPYDATA-dbbc7ed7

于 2013-12-13T18:29:29.333 に答える