在C++(MFC)应用程序和C#之间传递数据

8
我们有一个即将结束生命周期的 C++ 单体 MFC GUI 应用程序。我们计划在 C# 中构建新功能,并在两个应用程序之间传递数据。
问题是:C++ 和 C# 之间传递数据的最佳方法是什么?
注意事项:
两端都将有一个 GUI 前端,可能只需要传递像 Id 这样的简单数据,可能需要一种机制来指示另一个应用程序使用哪个进程/功能。
例如,其中一个应用程序将是 C# 中的 CRM 系统,当网格中的行被双击时,会传递 customerId 和消息,以打开该客户在 MFC 应用程序的“客户表单”中。
我已经做了一些研究,选项似乎是 Windows 消息、内存映射、命名管道或类似 Windows 套接字的东西。目前,我们倾向于使用 Named Pipes,但真的很感激其他建议、技巧或其他人的经验。
9个回答

7

个人而言,我会考虑使用命名管道,因为从C++方面很容易使用,而在.NET方面则可以使用System.IO.Pipes。

如果你计划逐步替换应用程序中的其他非.NET部分,这也将是最少阻力的路径。


1
请注意,自.NET 2.0以来,命名管道通过<code>System.IO.Pipes</code>命名空间得到支持。不需要使用DllImports。 - OwenP

6

选择一种方式:

  • 文件
  • 命名管道 <-- 我的建议
  • 共享内存
  • 套接字
  • COM
  • Windows消息

为什么选择命名管道?

  • 免费提供FIFO工作方式(像套接字,但不像共享内存)
  • 可以轻松地双向通信
  • 在所有平台上都有很好的支持
  • 易于使用
  • 可靠的数据传递和传递
  • 可以是阻塞和非阻塞的
  • 可以在不删除数据的情况下读取数据(不像套接字)
  • 可以轻松扩展以包括第三方应用程序。

在.Net中只需使用System.IO.Pipes。

在C++中使用CreateNamedPipe和CreateFile。


1
不是文件!我在处理那些一个程序写入文件,另一个程序(通过轮询)读取更改的系统上遇到了很多麻烦。 - Aardvark
不要仅仅重命名/删除/移动文件!文件正在使用中?只需循环并继续尝试!AAAA! :) - Aardvark
实际上,这可以相当干净地完成。注册文件系统通知。假设程序A在使用file.p1时使用它,并在不使用时将其重命名为.avail。程序2为.avail文件注册文件系统通知。 - Brian R. Bondy
当程序2在使用它时,它使用file.p2。然后每个程序都可以实现一个数据队列,等待进入文件。 - Brian R. Bondy
文件传输是一种广泛使用的机制,您可以为每个消息/事务编写一个文件,另一个应用程序等待目录更改通知以读取它。这很容易做到,但对于第三方通信更好。 - gbjbaanb
显示剩余2条评论

2

您也可以从托管代码中使用P/Invoke - 如果MFC应用程序具有C API,则这将非常有用。此外,您可以从任一侧使用COM。


2
您列出的选项确实是有效的,但您也可以考虑使用COM技术。

无论是COM还是DCOM都可以使用-这取决于应用程序是否在同一台机器上运行。 - 1800 INFORMATION
@Shaun Austin:实际上我是指COM :),这就是为什么我说COM的原因。 - QBziZ
我的错,抱歉,已经有一段时间忘记了COM EXE是外部进程!尴尬 - Shaun Austin
不用担心,你的声誉没有受损,评论旁边没有箭头[]-]。 - QBziZ

2

我会使用套接字 (TCP) - MFC 和 .NET 都直接支持它们。


1

你真的需要两个进程吗?

不受管理的 C++ 和托管的 C# 代码完全能够在同一个进程中运行,而通过一小层托管的 C++/CLI,您可以用简单的函数调用替换进程间通信的复杂性。


0

我会选择标准窗口消息(例如WM_FOO)或DCOM:

  • 只要通信非常简单,设置开销很小,消息就能够完成工作。如果你可以将通信简化为每个消息一个或两个整数,那么这可能是一个好的开始。如果两个应用程序都已经是窗口应用程序,则它们都已经有了消息循环,因此你已经完成了大部分工作。

  • DCOM需要更多的程序员开销,但好处在于你可以定义一个更丰富的接口,并避免将复杂消息转换为/从二进制形式。如果你选择这条路线,则CoRegisterClassObject是通过DCOM发布对象的起点。我从未尝试过从C#应用程序执行此操作,但原则上它完全可以实现


0

假设您拥有遗留应用程序的源代码,请尝试将所有“工作核心”代码编译为DLL,然后从那里调用各个函数/窗口。一旦您完成了这项工作,您可以简单地编写Managed C++包装器来包装您需要的函数,并从您的C#代码中调用它们。如果您很幸运,整个过程可能只需要不到一天的时间。


0

如果您不必担心应用程序将在所有系统上运行的.NET框架是否存在,我会建议使用C++/CLI,否则使用COM。但这真的取决于您最熟悉和熟练掌握的语言。我喜欢C++/CLI和COM现有的“函数调用”结构(而不是使用其他协议构建它),但这只是我的个人偏好。

目前,我正在使用COM添加一些.NET组件功能,主要是由于需要仍然具备回退功能,以防.NET不存在,但这仅适用于我需要的情况,其中最大部署是首选。


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