【问题标题】:Best way to communicate between .NET and native C++ application在 .NET 和本机 C++ 应用程序之间进行通信的最佳方式
【发布时间】:2015-09-03 18:44:47
【问题描述】:

如标题所述 - 目前我有两个应用程序。一种是 .NET、winforms,第二种是原生 C++。两者一起工作并且必须通信(C++ 到 .NET 和 .NET 到 C++),.NET 应用程序是从 C++ 应用程序启动的。目前,通信是通过将数据写入文件并发送 postmessage 通知 C++ 应用程序数据已写入来完成的。虽然它有效,但我认为这不是最好的方法。因此,我想问你,你会推荐什么作为最好的方法。我正在考虑围绕 .NET 编写一个 CLI 包装器以将其绑定到 C++ 中。与将数据写入文件相比,使用此类包装器有什么缺点吗?

--------更新--------

我忘了补充一点,两个应用程序总是在同一台机器上运行。该解决方案应适用于 Windows xp、win7、win8

-------结论------

非常感谢您的回答,所有这些都非常有帮助。关于进程间通信技术之间差异的良好概述呈现了 Furkan Omay 的答案中提供的网站 - offically supported Inter-Process Communications methods on Microsoft Windows。 但是,像 McAfee 的 web site 这样的防病毒程序似乎存在问题。在某些情况下,这可能是一个大问题。 根据使用 C++/Cli,我喜欢 Drax 的回答,谢谢。我也没有看到使用包装器的任何缺点。一个很好的教程是here。

【问题讨论】:

  • 为此使用网络 API 怎么样?例如本地 TCP/IP 连接。
  • 网络 + protobuf 例如github.com/google/protobuf
  • 命名管道也能正常工作。
  • 我不认为 Window 的消息是一种糟糕的交流方式。您在文件中存储了多少数据?如果少量,使用 WM_COPYDATA 消息 (msdn.microsoft.com/en-us/library/windows/desktop/…) 并避免文件 I/O 怎么样?
  • 另一种方法是使用 COM,但这对你来说可能是多余的

标签: c++ .net windows winforms


【解决方案1】:

通常我使用RegisterWindowMessage API 为两个应用注册自定义消息。

【讨论】:

    【解决方案2】:

    cli 包装器的主要(唯一?)缺点是它需要更多的开发时间,导致它的更多项目需要编写/调试/维护。但如果您的应用程序不小,这可能是最合理的解决方案。

    否则,您可以在其他通信层中进行选择,例如 NamedPipes 或 Sockets,它们非常通用,但添加了一个不必要的协议层,如果您将本机代码包装在 C++/Cli 中则不存在该协议层。这种语言就是为这个用例发明的。

    【讨论】:

      【解决方案3】:

      有几种方法可以实现这一点。

      1. 客户端/服务器连接

        您的应用程序需要侦听 TCP(首选)或 UDP 端口,而其他端口连接它。

        使您能够将应用程序分离到另一台计算机/网络接口。

        但是您在机器上保留了一个端口。您需要确保它受到互联网保护。一些内部防火墙可能会抱怨,即使在 localhost 上也是如此。 (但他们不会阻止它。)

      2. 命名管道

        你可以读写like a regular file。 .NET 已内置支持 System.IO.Pipes

        与纯文件方法的主要区别在于the application can wait 用于处理数据。这就像等待水从管道中流出一样。

        你需要处理好管道的方向和安全,然后妥善处理它们。

        Google Chrome 使用这种方法在不同的工作进程之间进行通信。

      3. Windows 消息调度

        就像提到的 i486 一样,您可以使用 RegisterWindowMessage 注册自定义消息并使用 SendMessage 或 PostMessage 发送它们。这是更 C++ 友好的方法。

        写得不好的应用程序可能会导致resource exhaustion,但这不会轻易发生。

      4. 邮槽

        这是由 Ian Goldby 建议的。 Mailslots 使用very simple Windows API Call 在应用程序之间提供单向消息发送。最适合发送大量小字符串。

      5. 消息队列

        您可以将您的应用程序连接到像RabbitMQ 这样的消息代理,并使用发布-订阅模型来传递数据。这需要一个您不想要的服务器,但是:

        您可以使用ZeroMQ,它可以在无服务器的情况下工作。它速度极快,可以通过不同的技术进行通信。但是,与以前的方法相比,它需要阅读更多的文档才能实现所需的行为。

      6. 标准输入/输出

        你可以重定向你的stdout,子进程可以通过stdin接收。

      根据您的要求,我个人会使用命名管道。它们留在计算机上,不需要对代码进行太多更改。以前我做了一个 C# 应用程序,它与用 C++ 编写的 OpenCV 应用程序通信,并且命名管道在这种情况下工作得很好。

      您可以用两种语言创建两个简单的类来在它们之间传递数据。

      但是,所有其他解决方案仍然有效。 TCP/IP 仍然可以在同一台机器上工作。消息、邮槽、套接字和管道是offically supported Inter-Process Communications methods on Microsoft Windows 之一,它们甚至可以在 Windows 2000 上运行。

      【讨论】:

      • 命名管道几乎可以肯定是这样做的。注意正确设置安全属性,否则恶意应用程序可能会劫持管道。 (如果 PC 有可能禁用网络,请避免使用 TCP/UDP。)
      • @IanGoldby 我已经用你超级简单的邮槽建议扩展了答案。
      • 感谢您的详细解释。但是这些方法的优缺点如何呢?正如您所说,命名管道应该与我当前使用的文件“相似”,并且代码不会有太多变化,但也没有太大的好处?如果我们想比较 cli 包装器和命名管道 - 是否有任何情况(性能、数据量、易于调试、添加新数据......)我们应该使用一个而不是另一个选项?
      • 关于命名管道的另一件事 - 我们能否始终确保防病毒软件不会阻止它们?
      • @MartinR 命名管道比文件好,因为你不需要 PostMessage(),你不可能在应用程序退出后文件仍然存在,数据从管道中删除通过阅读它,其他应用程序不会干扰它们,并且它们不受防病毒扫描的影响。
      【解决方案4】:

      我们有同样的问题。从.net到c++,我们调用dll,从c++到.net,我们构建一个本地web服务,为c++提供resful api

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-27
        • 1970-01-01
        相关资源
        最近更新 更多