首页 > 代码库 > WM_COPYDATA实现进程通信
WM_COPYDATA实现进程通信
在用Shuttle ESB完成C++程序和C#程序消息推送时,需要完成C++进程和ESB进程的通信问题。
进程间的通信方式有很多,比如使用内存映射文件、通过共享内存DLL共享内存、使用SendMessage向另一进程发送WM_COPYDATA消息。比起前两种的复杂实现来,WM_COPYDATA消息无疑是一种经济实惠的一中方法。
下面讲解如何通过WM_COPYDATA进行进行通信及通信原理。
1.建立SendMessage方法需要引用的数据结构:
namespace Entity { public class ReceiveMessage { public struct CopyDataStruct { public IntPtr dwData; public int cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; } } }2.在进程A和进程B分别对类库Entity进行引用:
3.在发送方构造SendMessage方法:
[DllImport("User32.dll", EntryPoint = "SendMessage")] private static extern int SendMessage(int hWnd, int Msg, int wParam, ref Entity.ReceiveMessage.CopyDataStruct lParam); [DllImport("User32.dll", EntryPoint = "FindWindow")] private static extern int FindWindow(string lpClassName, string lpWindowName); const int WM_COPYDATA = http://www.mamicode.com/0x004A;>SendMessage包含4个参数,hWnd:目标进程句柄,wMsg:用于区分其他消息的常量值,wParam:与消息有关的常量值,lParam:指向内存中数据的指针。
换成咱们的话就是:当前进程通过wMsg这种消息方式把lParam指向的内存数据传递到句柄为hWnd的进程中。
WM_COPYDATA的常量值0x004A代表“当一个应用程序传递数据给另一个应用程序时发送此消息”,WM不同的常量值代表不同的消息,更多WM_常量可以参考文章:WM_常量部分说明。WM_COPYDATA的常量值必须为0x004A,SendMessage才能完成进程消息传递,否则接收方可以检测到有消息到达,但无法接收消息内容。
4.在接收方通过DefWndProc回调方法完成消息捕获:
protected override void DefWndProc(ref Message m) { switch (m.Msg) { case WM_COPYDATA: Entity.ReceiveMessage.CopyDataStruct cds = new Entity.ReceiveMessage.CopyDataStruct(); Type t = cds.GetType(); cds = (Entity.ReceiveMessage.CopyDataStruct)m.GetLParam(t); string strResult = cds.dwData.ToString() + ":" + cds.lpData; txtReceiver.Text = strResult; break; default: base.DefWndProc(ref m); break; } }进程通信必须先启动接收方程序,因为发送方发送数据时需要检测接收方的句柄是否存在。SendMessage函数为阻塞式通信,当发送方的SendMessage函数开始执行时,接收方的DefWndProc函数会自动捕获发送方发送的数据。当DefWndProc函数执行完毕后,SendMessage函数才会继续执行。
这篇文章讲解的是如何模拟C++程序,将C++程序检测到的硬件数据通过WM_COPYDATA消息传送到ESB,下篇将会讲解ESB如何将数据通过观察者模式推送到各个客户端,大家敬请期待。WM_COPYDATA实现进程通信
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。