使用 IPC 组合多种语言
Posted
技术标签:
【中文标题】使用 IPC 组合多种语言【英文标题】:Using IPC to combine multiple languages 【发布时间】:2012-08-02 05:41:44 【问题描述】:这是一个关于软件设计的一般“菜鸟”问题,如果看起来含糊不清,我深表歉意, 但我真的很感激你的建议。请注意,下面描述的系统纯粹是一个示例,而不是我想到的特定产品。
我经常需要结合使用不同语言编写的多个库或实用程序的功能。例如,如果我想为桌面编写一个高性能的音频处理应用程序,我会用 C/C++ 编写它。然后,我想添加一个漂亮的 GUI。但我不想学习Qt。我喜欢 Adobe Air 的外观和感觉,并希望使用它。后来,我需要访问一个 USB 设备。但是我拥有的 USB 库只有一个 Java 的 API。如何将所有这些元素组合在一起,以利用它们的相对优势?
显然,我无法将这些不同的元素编译成一个可执行文件。所以我需要分别创建和运行它们,并为它们提供交流的方式。最常见的方法似乎是使用 IPC(进程间通信),例如共享内存或套接字。我更喜欢套接字的想法,因为这些程序可能会在网络上的不同机器上运行。
所以我决定创建一个带有自定义 API 的本地客户端/服务器系统,以允许这些元素进行通信。例如,Air 应用程序将收到来自 C 应用程序的消息,告诉它更新它的 UI。在 Java 中运行的 USB 应用程序将使用套接字将音频从 USB 硬件流式传输到 C 应用程序中。
我的问题:以这种方式使用本地套接字是设计此类系统的典型方式吗? 性能会比真正的原生应用程序(例如 Java 或 C 中的所有内容,在单个可执行文件中)差得多吗?这种方法似乎也很可能容易出现错误,并且难以维护?
我经常发现自己遇到了现有软件库的限制(例如,具有漂亮、灵活的 UI 但无法访问低级硬件的图形库,或者可以混合许多音频流但具有不支持视频播放),并觉得很沮丧。如果有人能建议像这样组合任意软件库的最佳方法,我将不胜感激。
提前致谢!
【问题讨论】:
【参考方案1】:正如您正确识别的那样,组合来自不同语言或平台的库是很困难的。有几种方法可以做到这一点,但没有一种是理想的。例子:
本机调用接口(例如 JNI / JNA) - 速度非常快,但难以正常工作,而且您遇到的问题是所使用的数据类型通常无法在不同平台之间干净地映射。添加本机依赖项。 带有文本协议(XML、JSON 等)的基于套接字的 IPC - 工作正常,两端可能都支持通用格式,但会增加很多开销。维护自定义架构映射等可能会很痛苦。 具有二进制协议(例如 Google 协议缓冲区)的基于套接字的 IPC - 非常高效,需要大量工作才能使自定义协议在两端正常工作 通过第三个系统(例如数据库、消息队列、文件系统)进行通信 - 大量开销,可能变得脆弱,引入了对第三个系统的主要依赖。根据我的经验,通常不值得仅仅为了获得一个特定的库或功能而集成一种新的语言/平台。以您的用户界面为例 - 无论 Adobe Air 看起来多么漂亮,我怀疑是否值得尝试将其与现有的 C/C++ 应用程序集成。
即使您让它工作,它也会使您的应用程序的未来维护和开发变得非常复杂。构建变得更加复杂。您需要维护额外的通信/“粘合”代码。您需要管理更多的依赖项。您的用户将受到更多配置问题的影响。测试变得更加困难。教新人整个系统如何工作变得更加困难。您需要在更多语言/框架等方面保持技能。
我推荐以下策略:
-
选择一个主要平台
每当您需要新的库或功能时,请先在您的主要平台上寻找一些东西。希望(通常?)有一些好的东西可用 - 但即使没有,如果需求非常小,也可能值得自己编写一些东西。
只有在主平台上没有合理的选择时,你才可以开始考虑整合新的语言/平台
就主要平台而言,我通常建议使用 Java、Scala 或 Clojure 之类的 JVM 语言,因为 JVM 设计精良、性能卓越、可移植性高,并且拥有最大/最具凝聚力的库生态系统(大部分这是开源的)。因此,JVM 可能是最好的“通用”选择,除非您有一些在 JVM 上不太可能实现的非常具体的要求,例如:
如果您正在进行大量需要硬件访问的嵌入式/实时/系统编程,您可能需要使用 C/C++ 如果您纯粹为基于 Web 的客户端编写代码,您可能希望使用 javascript(如果您也在服务器端编写代码,您可以考虑可以在 JVM 上运行的 JavaScript 代码生成框架/库,例如 Vaadin 或ClojureScript)【讨论】:
两个很好的答案,但这个更容易理解。由于我的大部分工作都需要 C/C++,我认为将 Qt 作为我的“平台”可能是安全的。【参考方案2】:答案在很大程度上取决于您使用的技术,对此没有灵丹妙药的解决方案。
一般而言,此解决方案将属于以下类别之一:
一些进程间通信技术
语言/平台本身提供的集成
数据库/一些通用存储(甚至文件:))
第一个例子: 套接字/管道/操作系统允许的任何东西。 CORBA - 允许用不同的语言编写分布式代码。 Google protobuf - 允许数据对象的序列化/反序列化及其语言不可知
第二个方面,它实际上取决于您使用的语言/生态系统。 java的例子:
JNI - Java Native 接口 - 允许在 JVM 之外执行代码 (dlls/so)。 JCA - 如果您在企业环境中 - 您可以在其中编写与遗留系统的集成。对于编译成本机代码的语言,它不那么棘手 - 您可以编写和编译一些代码,比如用 Pascal,然后在 C 中使用 DLL。
有时当我们谈论 Java 时,有很多语言都有自己的语法和编译器,但它们的编译器编译成可以在 jvm 中运行的 java 二进制代码。因此,如果您的解决方案基于这些语言,则集成会更容易。 Scala、Groovy、Closure、Jython 等语言都属于这一类。
最后但并非最不重要的技术是 Web 服务。这是一个非常流行的用于集成不同系统的工具,尽管它更多地用于企业环境。 基本上它是对套接字层的抽象,允许在进程/服务器之间以 XML/JSON 格式发送数据对象。 XML 和 JSON 都与语言无关,因此在用 C++ 编写的程序中创建 XML 然后在 JAVA 中使用它不是问题。
希望对你有帮助
【讨论】:
以上是关于使用 IPC 组合多种语言的主要内容,如果未能解决你的问题,请参考以下文章