.NET和本地C++应用程序之间通信的最佳方法

5
目前我有两个应用程序,一个是.NET的winforms,另一个是本地的C++。两者必须相互通信(C++与.NET和.NET与C++),.NET应用程序是从C++应用程序启动的。目前通过将数据写入文件并发送PostMessage来通信。虽然这样做可以工作,但我认为这不是最好的方法。因此,我想请问您,您会推荐哪种方式作为最佳方式?我考虑编写CLI包装器以将.NET绑定到C++中。与将数据写入文件相比,使用这种包装器是否存在任何缺点?
--------更新--------
我忘记添加两个应用程序始终在同一台计算机上运行。解决方案应适用于Windows xp、win7、win8。
-------结论------
非常感谢您的回答,它们都非常有帮助。关于进程间通信技术的差异,Furkan Omay提供的网站offically supported Inter-Process Communications methods on Microsoft Windows提供了很好的概述。 然而,像 McAfee 这个 网站 上的杀毒软件似乎存在问题,在某些情况下可能会成为一个巨大的问题。 根据使用 C++/Cli 的经验,我喜欢 Drax 的答案,谢谢。我也没有看到使用包装器的任何缺点。这里有一个很好的教程here

1
使用网络API如何?例如本地TCP/IP连接。 - Binkan Salaryman
命名管道也很有效。 - Furkan Omay
我认为Windows消息不是一种糟糕的通信方式。您在文件中存储了多少数据?如果只有少量数据,那么使用WM_COPYDATA消息(https://msdn.microsoft.com/en-us/library/windows/desktop/ms649011(v=vs.85).aspx)来避免文件I/O如何? - jglouie
另一种方法是使用COM,但这可能对你来说有些过度了。 - jglouie
感谢您的回复。文件中没有太多的数据,根据配置大约有20-50个不同的信息。 - Martin R
显示剩余3条评论
4个回答

9

有几个选项可以实现这个目标。

  1. 客户端/服务器连接

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

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

    但您需要在计算机上保留一个端口。您需要确保它受到互联网的保护。即使在本地主机上,一些内部防火墙也可能会发出警告。(但它们不会阻止它。)

  2. 命名管道

    您可以像读写常规文件一样读写它。 .NET具有内置支持,使用System.IO.Pipes

    与纯基于文件的方法相比,主要区别在于应用程序可以等待数据进行处理。就像等待水从管子里流出来一样。

    您需要处理管道的方向和安全性,然后正确处理它们。

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

  3. Windows消息分派

    如i486所述,您可以使用RegisterWindowMessage为自定义消息注册并使用SendMessage或PostMessage发送它们。这是更适合C ++的方法。

    编写不良的应用程序可能会导致资源耗尽,但不会轻易发生。

  4. 邮槽

    这是Ian Goldby建议的。邮槽提供了应用程序之间单向消息发送的非常简单的Windows API调用。最适合发送大量小字符串。

  5. 消息队列

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

    您可以使用ZeroMQ,它可以无需服务器即可工作。它非常快速,可以通过不同的技术进行通信。但是,为了实现所需的行为,需要阅读比以前的方法更多的文档。

  6. 标准输入/输出

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

根据您的要求,我个人会使用命名管道。它们留在计算机上,不需要太多代码更改。之前我做过一个C#应用程序,与用C++编写的OpenCV应用程序通信,命名管道在那种情况下完美地工作。

您可以在两种语言中创建两个简单的类来传递数据。

然而,所有其他解决方案仍然可行。TCP/IP仍然可以在同一台机器上工作。消息、邮槽、套接字和管道是Microsoft Windows上官方支持的进程间通信方法之一,它们甚至可以在Windows 2000上工作。


1
命名管道几乎肯定是实现这一点的方法。请注意正确设置安全属性,否则恶意应用程序可能会劫持管道。(如果有任何可能PC禁用网络,请避免使用TCP/UDP。) - Ian Goldby
@IanGoldby 我已经采纳了你的超级简单的邮槽建议并扩展了答案。 - Furkan Omay
感谢您的详细解释。但是这些方法的优缺点如何呢?您说命名管道应该与我目前正在使用的文件“类似”,代码不会有太多变化,但好处也不会太多吧?如果我们想比较cli包装器和命名管道 - 在性能、数据量、调试方便性、添加新数据等方面是否有任何情况需要选择其中一种而不是另一种选项? - Martin R
关于命名管道还有一件事情 - 我们能否始终确信防病毒软件不会阻止它们? - Martin R
@MartinR 命名管道比文件更好,因为您不需要使用PostMessage(),您不必担心应用程序退出后文件仍然存在的可能性,通过读取数据可以从管道中删除数据,其他应用程序无法干扰它们,并且它们不会受到杀毒软件扫描的影响。 - Ian Goldby

1
主(唯一?)缺点是cli包装器需要更多的开发时间,因为它需要编写/调试/维护一个额外的项目。但是,如果您的应用程序不是小型应用程序,则可能是最可靠的解决方案。
否则,您可以选择其他通信层,例如NamedPipes或Sockets,这些通信层相当通用,但会添加一个不必要的协议层,如果您在C++/Cli中包装本机代码,则不存在这个协议层。这种语言正是为此用例而发明的。

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

0

我们遇到了同样的问题。从 .NET 调用 DLL 到 C++,从 C++ 调用 .NET,我们建立了一个本地 Web 服务,为 C++ 提供 RESTful API。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接