2012-08-02 77 views
5

这是一个关于软件设计的普遍“noob”问题,所以如果看起来模糊不清,我很抱歉,但我真的很感谢这个建议。注意下面描述的系统纯粹是一个例子,而不是我想到的特定产品。使用IPC结合多种语言

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

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

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

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

我经常发现自己遇到了现有软件库的限制(例如,图形库具有漂亮灵活的用户界面,但无法访问底层硬件,或者可以混合多种音频流的媒体库,但不支持视频播放),并发现它非常令人沮丧。如果任何人可以建议这样的任意软件库的最佳方式,我会很感激。

在此先感谢!

回答

4

正如你正确识别,从不同的语言或平台组合库是很难的。有几种方法可以做到,但没有一种是理想的。例子:

  • 本地调用接口(JNI例如/ JNA) - 非常快,但棘手使正常工作,并且您有通常使用的数据类型不跨越不同的平台上工整地映射的问题。添加本地依赖项。
  • 带有文本协议(XML,JSON等)的基于套接字的IPC - 工作正常,并且通用格式可能在两端受到支持,但会增加很多开销。可能很难保持自定义模式映射等
  • 基于套接字的IPC与二进制协议(例如Google协议缓冲区) - 效率很高,需要大量工作才能使定制协议在两端都能正常工作
  • 通过通信第三个系统(例如数据库,消息队列,文件系统) - 很多开销,可能会变得脆弱,引入对第三个系统的主要依赖。

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

即使你得到它的工作,它将会明显复杂化您的应用程序的未来维护和发展。构建变得更加复杂。您需要维护额外的通讯/“胶水”代码。你需要管理更多的依赖关系。你的用户会遇到更多的配置问题。测试变得更加困难。教新人关于整个系统如何工作变得更加困难。你需要在更多的语言/框架中保持你的技能。

我推荐以下策略:

  1. 选择一个主要平台
  2. 每当你需要一个新的图书馆或功能,寻找一些主平台上的第一。希望(通常?)有很好的可用性 - 但即使不是这样,如果要求很小,自己也可能需要编码。
  3. 只有在有的主要平台上没有合理的选择,那么你就可以开始考虑集成一个新的语言/平台

在主要平台而言,我通常建议一个JVM语言如Java,Scala或Clojure,因为JVM设计精良,性能卓越,可移植性强,拥有最大/最紧密的图书馆生态系统(其中大部分为开源)。因此,JVM可能是最好的“通用”的选择,除非你有一些非常具体的要求,这是不太可能保持在JVM上,如:

  • 如果你正在做大量的嵌入式/实时/系统编程wthat的需要硬件访问你可能需要去C/C++
  • 如果你纯粹为基于web的客户端编码,你可能想要使用JavaScript(如果你也在服务器端编写代码,你可以考虑使用JavaScript代码生成框架/可以在JVM上工作的库,例如Vaadin或ClojureScript)
+0

这两个很好的答案,但这一个是eas更加明白。 我的许多工作都需要C/C++,我认为将Qt作为我的“平台”可能是安全的。 – darasan 2012-08-03 07:42:05

2

答案很大程度上取决于您正在使用的技术,因此没有银子弹解决方案。

在一般情况下,这种解决方案将分为以下类别之一:

  • 一些进程间通信技术由语言/平台提供

  • Integrations公司本身

  • 数据库/一些通用存储(甚至文件:))

第一个示例: 套接字/管道/无论您的操作系统允许。 CORBA - 允许使用不同的语言编写分布式代码。 谷歌protobuf - 允许序列化/反序列化的数据对象和其语言不可知论者

第二,它真的取决于你使用的语言/生态系统。 java的示例:

  • JNI - Java Native接口 - 允许在JVM外部执行代码(dlls/so)。
  • JCA - 如果您处于企业环境中 - 您可以在此编写与遗留系统的集成。

对于被编译为本地代码语言其较有难度的 - 你可以编写和编译一些代码,在帕斯卡尔说,然后使用DLL在C

有时,当我们谈论Java有很多种语言都有自己的语法和编译器,但是它们的编译器会编译成可以在jvm中运行的java二进制代码。因此,如果您的解决方案基于这些语言,那么整合将更容易。 Scala,Groovy,Closure,Jython等语言都属于这一类。

最后但并非最不重要的技术是Web服务。这是一个非常受欢迎的不同系统集成工具,尽管它在企业环境中更多使用。 基本上它是一个套接字层的抽象,它允许在进程/服务器之间以XML/JSON格式发送数据对象。 XML和JSON都是与语言无关的,所以在用C++编写的程序中创建XML并在JAVA中使用它时,这不是问题。

希望这有助于