从 C++ 到 C# 的 WM_COPYDATA

Posted

技术标签:

【中文标题】从 C++ 到 C# 的 WM_COPYDATA【英文标题】:WM_COPYDATA from c++ to C# 【发布时间】:2013-02-07 16:41:23 【问题描述】:

我正在使用 Visual Studio 2010 开发 4 个应用程序(使用 Internet 中的已建立示例):2 个在 C++ MFC 中(名为:SenderCpp 和 ReceiverCpp),2 个在 C# 中(名为:SenderCsh 和 ReceiverCsh),以测试 WM_DATACOPY 进程间通信。

我的目标是让 C++ 应用程序“SenderCpp”向 C# 应用程序“ReceiverCsh”发送一些数据,但它不起作用,“ReceiverCsh”没有收到任何消息。

所以:

SenderCpp->ReceiverCpp:工作 SenderCsh->ReceiverCsh:工作 SenderCpp->ReceiverCsh:不起作用

SenderCpp 代码为:

void SendCopyData(HWND hFind)

    COPYDATASTRUCT cp;
    StackRecord record;

    record.CursorX = 1;
    record.CursorY = -1;

   _tcscpy(record.cmdline, L"Hello World!");
   cp.cbData = sizeof(record);
   cp.lpData = &record;
   cp.dwData = 12;
   SendMessage(hFind, WM_COPYDATA, NULL, (LPARAM)&cp);


void CCANDriverDlg::OnBnClickedButton2()

   HWND hWnd = ::FindWindow(NULL, CString("ReceiverCpp"));
   SendCopyData(hWnd);


void CCANDriverDlg::OnBnClickedButton1()

   HWND hWnd = ::FindWindow(NULL, CString("ReceiverCsh"));
   SendCopyData(hWnd);

ReceiverCsh 是:

 protected override void WndProc(ref Message m)
    
        switch(m.Msg)
        
            case WM_COPYDATA:
                // Win32.CopyDataStruct st = (Win32.CopyDataStruct)Marshal.PtrToStructure(m.LParam, typeof(Win32.CopyDataStruct));
                CopyDataStruct st = (CopyDataStruct)Marshal.PtrToStructure(m.LParam, typeof(CopyDataStruct));
                //txtmessagereceive.Text = strData;

                CANMessage MsgIn = new CANMessage(8);
                MsgIn = (CANMessage)Marshal.PtrToStructure(st.lpData, typeof(CANMessage));

                // Decode the marshaled message
                txtmessagereceive.Text = "dwData = " + st.dwData.ToString() +"\r\n" +
                                        "cbData = " + st.cbData + " bytes\r\n" +
                                        "CANID = " + MsgIn.CANID.ToString() + "\r\n";
                for (int i=0; i<8; i++)
                
                    txtmessagereceive.Text += String.Format("Data[0]=1\r\n", i, MsgIn.Data[i]);
                

                break;
            default:
                // let the base class deal with it
                base.WndProc(ref m);
                break;
        
    

使用 Spy++ 我看到监视“ReceiverCsh”时,SenderCpp 发送 WM_COPYDATA 时没有显示消息,而是在分析 ReceiverCpp 时显示消息。

你有什么想法吗? 谢谢。

【问题讨论】:

WM_COPYDATA 是一种相当糟糕的数据交换方式。找到合适的窗口句柄从来都不是那么简单,UIPI 一直是个令人头疼的问题。省略所有错误检查会使情况变得更糟,需要对窗口句柄进行空检查。请改用命名管道或套接字。 您是否在 C# WndProc 中看到 any 窗口消息?您是否验证了您在 C++ 端发送到的窗口句柄值与在 C# 端的 WndProc 表单上相同? 是的,我使用 Spy++ 验证了这一点。我在两种情况下(OnBnClickedButton1 和 2)都设置了一个断点来查看 FindWindow() 的返回值,它们与 Spy++ 上读取的句柄一致。当应用程序调用 Marshal.PtrToStructure() 时,我还在 WndProc 中插入了一个断点,当 C++ 发送消息时永远不会停止。 【参考方案1】:

我想知道ReceiverCsh 是否是一个控制台应用程序。为了使用 WndProc 覆盖,您需要有一个消息泵来接收外部消息。确保是这种情况。

详情请见Handling Messages in Console Apps

【讨论】:

不,不是控制台应用,都是windows窗体。

以上是关于从 C++ 到 C# 的 WM_COPYDATA的主要内容,如果未能解决你的问题,请参考以下文章

从 C# 到 C++ 触发 COM 事件的正确方法是啥

从 C++ 到 C# 的编码

将引用类型从 C++ 编组到 C#

从 C# 切换到 C++。有啥必读的吗? [关闭]

从 c++ 到 c# 的 pinvoke 字节数组

如何将对象列表从 C++ 传递到 C#?