【问题标题】:Passing data between C++ (MFC) app and C#在 C++ (MFC) 应用程序和 C# 之间传递数据
【发布时间】:2010-09-16 03:12:51
【问题描述】:

我们有一个单片 MFC GUI 应用程序,它在 C++ 中的生命周期已接近尾声。我们计划在 C# 中构建新功能并在每个应用程序之间传递数据。

问题是:在 C++ 和 C# 之间传递数据的最佳方法是什么?

注意事项:
两端都将有一个 GUI 前端,并且可能只需要传递像 Id 这样的简单数据,并且可能有一个机制,它可以向其他应用程序指示要使用的进程/功能。
例如,其中一个应用程序是 C# 中的 CRM 系统,当双击网格中的一行时,会传递 customerId 和一条消息,以在 MFC 应用程序的客户表单中打开该客户。

我做了一些研究,选项似乎是 Windows 消息传递、内存映射、命名管道或类似 Windows 套接字的东西。在这个阶段,我们倾向于命名管道,但非常感谢其他建议或技巧或其他人的经验。

【问题讨论】:

    标签: c# c++ ipc


    【解决方案1】:

    我个人会考虑使用命名管道之类的东西,因为它们在 C++ 端和 .NET 端的 System.IO.Pipes 都很容易使用。

    如果您打算随着时间的推移替换应用程序的其他非 .NET 位,这也可能是阻力最小的路径。

    【讨论】:

    • 请注意,从 .NET 2.0 开始,通过 System.IO.Pipes 命名空间支持命名管道。不需要 DllImports。
    【解决方案2】:

    任你选:

    • 文件
    • 命名管道
    • 共享内存
    • 套接字
    • COM
    • Windows 消息

    为什么要命名管道?

    • 为您提供一种 FIFO 的免费工作方式(类似于套接字,但不像共享内存)
    • 可以轻松地双向交流
    • 在所有平台上都得到很好的支持
    • 易于使用
    • 可靠的数据传递和传递
    • 可以是阻塞式和非阻塞式
    • 无需移除即可读取数据(与套接字不同)
    • 可以轻松扩展以包含第三个应用程序。

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

    在 C++ 中使用 CreateNamedPipe 和 CreateFile。

    【讨论】:

    • 不是文件!我在处理一个程序中的文件并(通过轮询)读取另一个程序中的更改的系统上工作时遇到了麻烦。
    • 嗯,是的,但您当然可以创建另一个文件,让第一个文件知道您已经完成了它的工作。开个玩笑:)这只是一种选择,不是推荐的:)
    • 不只是重命名/删除/移动文件!正在使用的文件?只需循环并继续尝试!啊啊啊! :)
    • 其实可以很干净的完成。注册文件系统通知。假设程序 A 在使用时使用 file.p1 并在不使用时重命名为 .avail 。程序 2 为 .avail 文件注册文件系统通知。
    • ... 当程序 2 使用它时,它使用 file.p2。然后每个程序可以实现一个等待进入文件的数据队列。
    【解决方案3】:

    您还可以从托管端使用 P/Invoke - 如果 MFC 应用具有 C API,这将很有用。您也可以从任一侧使用 COM。

    【讨论】:

      【解决方案4】:

      您列出的选项当然是有效的,但您也可以考虑 COM。

      【讨论】:

      • COM 或 DCOM 都适合 - 取决于应用程序是否在同一台机器上运行
      • @Shaun Austin : 其实我的意思是 COM :),这就是我说 COM 的原因。
      • 我的错,对不起,有一段时间忘记了 COM EXE 正在处理之外! 尴尬
      • 别担心,你的名声没有受损,评论旁边没有箭头[]-]
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        你真的需要两个进程吗?

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

        【讨论】:

          【解决方案7】:

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

          • 只要通信非常简单,消息就可以工作,并且设置它的开销很小。如果您可以将通信简化为每条消息一到两个整数,那么这可能是一个不错的起点。如果这两个应用程序都已经是窗口应用程序,那么它们都已经有消息循环,所以你已经大部分时间了。

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

          【讨论】:

            【解决方案8】:

            假设您拥有旧版应用程序的源代码,请查看是否无法将所有“主力”代码编译为 DLL,然后从那里调用各个函数/窗口。一旦你完成了这项工作,你就可以简单地围绕你需要的函数编写托管 C++ 包装器,并从你的 C# 代码中调用它们。如果幸运的话,整个过程可能需要不到一天的时间。

            【讨论】:

              【解决方案9】:

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

              我目前正在使用 COM 来添加一些 .NET 组件功能,主要是因为如果 .NET 不存在,仍然需要使用后备功能,但这是特定于我的需求,最好进行最大部署。

              【讨论】:

                猜你喜欢
                • 2015-06-26
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多