繁体   English   中英

什么是本机C / C ++和C#(.NET)之间最轻的IPC解决方案?

[英]What is the lightest IPC solution between native C/C++ and C# (.NET)?

我有一个原生的C ++ Visual Studio 2010解决方案,我想将数据发送到.NET应用程序(C#WPF)有没有办法用几行C / C ++代码执行此操作? 我不想在C / C ++端使用外部依赖项。 有关于此的示例代码吗?

更多信息:C / C ++本机应用程序实际上是一个加载到chrome.exe进程的npapi dll。 我不认为这很重要,请证实。

听起来你可以使用命名管道在进程之间进行通信。

这个问题应该有助于指出你正确的方向。

我推荐Named Pipes; 是C#和C ++之间命名管道实现的一个很好的例子。 您还可以实现COM Interop 另一种方法是使用WM_COPYDATA消息(要捕获它们,你需要覆盖WndProc),但这些消息非常有限:

public static class CopyDataHelper
{
    [StructLayout(LayoutKind.Sequential, Pack=1)]
    public struct COPYDATASTRUCT
    {
        private Int32 _dwData;
        private Int32 _cbData;
        private IntPtr _lpData;

        public Int32 DataId
        {
            get { return _dwData; }
            set { _dwData = value; }
        }

        public Int32 DataSize
        {
            get { return _cbData; }
        }

        public IntPtr Data
        {
            get { return _lpData; }
        }

        public T GetData<T>() where T : struct
        {
            return (T)Marshal.PtrToStructure(_lpData, typeof(T));
        }

        public void SetData<T>(T data) where T : struct
        {
            Int32 size = Marshal.SizeOf(typeof(T));
            IntPtr ptr = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(data, ptr, true);

            _cbData = size;
            _lpData = ptr;
        }
    }

    [DllImport("User32.dll", CharSet=CharSet.Unicode, ExactSpelling=true, SetLastError=true)]
    [return:  MarshalAs(UnmanagedType.Bool)]
    internal static extern Boolean SendMessage([In] IntPtr hWnd, [In] UInt32 msg, [In] IntPtr wParam, [In, Out] ref COPYDATASTRUCT lParam);

    public const Int32 WM_COPYDATA = 0x004A;

    public static Boolean Send<T>(IntPtr fromHwnd, IntPtr toHwnd, Int32 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!");

        return (COPYDATASTRUCT)msg.GetLParam(typeof(COPYDATASTRUCT));
    }   
}

// Override

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

最后一次机会是使用谷歌的协议缓冲区:原始实现仅支持C ++,Java和Python ......但对于.NET,有protobuf-net

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM