【问题标题】:IPC between .NET and C++ applications.NET 和 C++ 应用程序之间的 IPC
【发布时间】:2011-01-02 00:04:39
【问题描述】:

.NET 应用程序和本机 C++ 应用程序之间是否有任何用于进程间通信 (IPC) 的库?

【问题讨论】:

    标签: .net c++ ipc


    【解决方案1】:

    您可以使用 Socket 进行简单的通信。它在操作系统中,因此您不需要任何新库。详细信息在C++ SocketC# Socket

    如果进程间通信总是要在同一台机器上完成,命名管道是可行的方法,因为它们比其他选项更快。

    【讨论】:

      【解决方案2】:

      一个简单(虽然有限)的 IPC 机制是WM_COPYDATA message

      您可以轻松使用它将结构传输到本机应用程序。

      我使用以下辅助类:

      public static class CopyDataHelper
      {
      
          [StructLayout(LayoutKind.Sequential)]
          public struct COPYDATASTRUCT
          {
              private int _dwData;
              private int _cbData;
              private IntPtr _lpData;
      
              public int DataId
              {
                  get { return _dwData; }
                  set { _dwData = value; }
              }
      
              public int DataSize
              {
                  get { return _cbData; }
              }
      
              public IntPtr Data
              {
                  get { return _lpData; }
              }
      
              public void SetData<T>(T data) where T : struct
              {
                  int size = Marshal.SizeOf(typeof(T));
                  IntPtr ptr = Marshal.AllocHGlobal(size);
                  Marshal.StructureToPtr(data, ptr, true);
                  _lpData = ptr;
                  _cbData = size;
              }
      
              public T GetData<T>() where T : struct
              {
                  return (T)Marshal.PtrToStructure(_lpData, typeof(T));
              }
          }
      
          [DllImport("User32.dll")]
          private static extern bool SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
      
          public const int WM_COPYDATA = 0x004A;
      
          public static bool Send<T>(IntPtr fromHwnd, IntPtr toHwnd, int dataId, T data) where T : struct
          {
              IntPtr ptr = IntPtr.Zero;
              try
              {
                  COPYDATASTRUCT cds = new COPYDATASTRUCT();
                  cds.DataId = dataId;
                  cds.SetData(data);
                  return SendMessage(toHwnd, WM_COPYDATA, fromHwnd, ref cds);
              }
              finally
              {
                  if (ptr != IntPtr.Zero)
                      Marshal.FreeHGlobal(ptr);
              }
          }
      
          public static COPYDATASTRUCT Receive(Message msg)
          {
              if (msg.Msg != WM_COPYDATA)
                  throw new ArgumentException("This is not a WM_COPYDATA message");
              COPYDATASTRUCT cds = (COPYDATASTRUCT)msg.GetLParam(typeof(COPYDATASTRUCT));
              return cds;
          }
      
      }
      

      要捕获 WM_COPYDATA 消息,您需要覆盖 WndProc

          protected override void WndProc(ref Message msg)
          {
              if (msg.Msg == CopyDataHelper.WM_COPYDATA)
              {
                  CopyDataHelper.COPYDATASTRUCT cds = CopyDataHelper.Receive(msg);
                  if (cds.DataId == myDataId)
                  {
                      MyData data = cds.GetData<MyData>();
                      msg.Result = DoSomething(data);
                      return;
                  }
              }
      
              base.WndProc(ref msg);
          }
      

      【讨论】:

        【解决方案3】:

        检查 Google 的协议缓冲区 (protobuf)。 原始实现支持 C++、Java 和 Python,但对于 .NET,有 protobuf-net

        【讨论】:

          【解决方案4】:

          Named pipes 或我使用过的COM Interop 都是不错的选择。

          【讨论】:

            猜你喜欢
            • 2016-03-22
            • 1970-01-01
            • 2010-09-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多