使用IPC结合多种语言

dar*_*san 6 c java air ipc shared-libraries

这是一个关于软件设计的一般"noob"问题,所以如果它看起来模糊不清我道歉,但我真的很感激这个建议.请注意,下面描述的系统纯粹是一个示例,而不是我想到的特定产品.

我经常需要结合使用不同语言编写的几个库或实用程序的功能.例如,如果我想为桌面编写高性能音频处理应用程序,我将用C/C++编写它.然后,我想添加一个漂亮的GUI.但我不想学习Qt.我喜欢Adobe Air的外观和感觉,并希望使用它.后来,我需要访问USB设备.但USB库我只有一个Java API.如何将所有这些元素组合在一起,以利用它们的相对优势?

显然,我无法将这些不同的元素编译成一个可执行文件.因此,我需要单独创建和运行它们,并为它们提供一种通信方式.最常见的方法似乎是使用IPC(进程间通信),例如共享内存或套接字.我更喜欢套接字的想法,因为程序可能会在网络上的单独机器上运行.

因此,我决定使用自定义API创建本地客户端/服务器系统,以允许这些元素进行通信.例如,Air应用程序将从C应用程序接收消息,告诉它更新它的UI.在Java中运行的USB应用程序将使用套接字将来自USB硬件的音频流传输到C应用程序中.

我的问题:以这种方式使用本地套接字是设计这样一个系统的典型方法吗?性能是否会比真正的本机应用程序(例如Java或C中的所有内容,在单个可执行文件中)更糟糕?这种方法似乎很容易出错,难以维护?

我经常发现自己遇到了现有软件库的限制(例如图形库具有漂亮,灵活的UI但无法访问低级硬件,或者媒体库可以混合许多音频流,但不支持视频播放),发现它非常令人沮丧.如果有人可以建议最好的方法来组合像这样的任意软件库,我真的很感激.

提前致谢!

mik*_*era 5

正如您已经正确识别的那样,组合来自不同语言或平台的库很难.有几种方法可以做到,但没有一种方法是理想的.例子:

  • 本机调用接口(例如JNI/JNA) - 非常快速但难以正常工作,并且您遇到的问题是所使用的数据类型通常不会在不同平台上干净地映射.添加本机依赖项.
  • 基于套接字的IPC与文本协议(XML,JSON等) - 工作正常,两端可能支持常见格式,但会增加很多开销.维护自定义架构映射等可能会很痛苦.
  • 基于套接字的IPC与二进制协议(例如Google协议缓冲区) - 非常高效,需要大量工作才能使自定义协议在两端正常工作
  • 通过第三个系统(例如数据库,消息队列,文件系统)进行通信 - 大量开销可能变得脆弱,引入了对第三个系统的主要依赖性.

根据我的经验,通常不值得集成新的语言/平台只是为了获得一个特定的库或功能.以您的用户界面为例 - 无论Adobe Air看起来多么好看,我怀疑是否值得尝试将其与现有的C/C++应用程序集成.

即使您使用它,也会使应用程序的未来维护和开发变得非常复杂.构建变得更加复杂.您需要维护额外的通信/"粘合"代码.您需要管理更多依赖项.您的用户将受到更多配置问题的影响.测试变得更加困难.向某人讲述整个系统如何工作变得更加困难.您需要在更多语言/框架等方面保持技能.

我推荐以下策略:

  1. 选择一个主要平台
  2. 每当您需要新的库或功能时,请先在主平台上查找.希望(通常是?)有一些好东西 - 但即使没有,那么如果要求非常小,那么自己编码可能是值得的.
  3. 只有在主平台上没有合理的选项时,您才可以开始考虑集成新的语言/平台

在主平台方面,我通常建议使用Java,Scala或Clojure等JVM语言,因为JVM设计精良,性能卓越,可移植性高,拥有最大/最具凝聚力的库生态系统(大多数是开放的)资源).因此,JVM可能是最好的"通用"选择,除非您有一些非常具体的要求,这在JVM上是不可能的,例如:

  • 如果您正在进行大量需要硬件访问的嵌入式/实时/系统编程,您可能需要使用C/C++
  • 如果您纯粹是为基于Web的客户端编写代码,那么您可能希望使用JavaScript(如果您还在服务器端编写代码,则可以考虑可以在JVM上运行的JavaScript代码生成框架/库,例如Vaadin或ClojureScript)