背景:我们正在设计一个物理应用程序,它将进行大量数据分析,但我们的重点是集成物理电子设备。

基本上我希望能够打电话 (这是一个来自CERN的大数据分析库,用C++编写)用Java的C++库编写的库。基本上,使用 Java 中的 ROOT 类的能力(并且不会浪费太多时间来编写 JNI 包装器)对我们来说是一个亮点(如果这很难,我们很可能会使用 Qt)。

我可以想到以下方法

  • JNI - 正如我所说 - 我们不想为每个类编写包装器。。。
  • JNA - JNA 不提供 C++ 映射,而只提供 C。
  • 斯威格 - 我没用过,但听说很难用。

其他可能相关的事情:我们可以访问根源代码,但我们不想更改它。我们希望结果是可移植的。我们希望坚持使用免费图书馆。正如我所说 - 我们将能够从一开始就使用大部分 ROOT 代码,无需大惊小怪。

有帮助吗?

解决方案

无论选择什么,您都需要进行一些包装。虽然您不想为每个类编写 JNI 包装器,但您可以编写包含方法组的更高级别的 C++ 类。然后你只需要为更高级别的类编写包装器(这种方法也适用于其他方法,而不仅仅是 JNI)。

其他提示

编写一个小型 C++ 应用程序,从 stdin 读取输入并将输出写入 stdout。然后从 java 应用程序中运行该进程并从 stdout 读取输出。

这是在没有 JNI 的情况下实现此目的的最佳方法(而且非常容易做到)

我会推荐 Dropbox 的 djinni 界面生成工具. 。他们将其用于跨平台移动应用程序,以生成 Java (Android) 和 Objective-C (iOS) 接口及其 C++ 数据模型之间的接口。

脸书也用过 他们的应用程序之一。所以我认为,它经过了很好的测试。

查看他们在 CppCon 上的演讲 了解其作用的概述。使用 JNI 在 Java 和 C++ 之间进行接口似乎特别容易出错。

JNI易 支持 C++ 类到 Java POJO 类的映射,但价格为 399 欧元。由于您更喜欢免费库,因此您可能想要寻找使用 CORBA 之类的解决方案。这是将 C++ 类映射到 Java 类的唯一方法。

编辑:你有没有考虑过 JAS3, ,它是一个类似于root的java库吗?

只是一个想法,但你可以使用 Python,因为 Root 已经支持它了?您很可能会相当熟练地掌握包装 Java 代码所需的时间。

考虑使用 C# 而不是 Java。如果您已经熟悉 java,那么切换到 C# 很容易,而且它有 更好的支持 用于调用本机代码。

用 C++ 编写所需的类/函数,然后从 java 中编译并调用 exec() 怎么样?

每当您通过 JNI 或等效方法从 Java 调用 C 或 C++ 代码时,您都会面临由于 C/C++ 端的内存管理和/或线程安全问题而导致 Java 平台不稳定的风险。

在走 JNI 等路线之前,我认为你应该考虑其他选择:

  • 将 Java 排除在外,完全用 C++ 实现(或者像其他人建议的那样用 C++ / CC# 实现)。
  • 创建一个 C++ 命令行应用程序来执行您需要使用本机库执行的任务,并使用其中之一运行该应用程序 java.lang.Runtime.exec 方法。
  • 用 C++ 为该库创建一个“服务器”包装器,该包装器将您需要的功能公开为自定义协议,并编写 Java 端代码以使用 HTTP、原始套接字、管道或任何适当的传输级别与服务器通信。

所有替代方案都有缺点,JNI / JNA 等也有缺点;见第一段。

编辑:当您决定在系统中使用 JNI / JNA 时,可能会产生长期后果。除了稳定性问题之外,你还必须考虑可移植性(原生库是否可以在 Windows、Linux 等上运行)、构建问题(很难在 Ant 等中构建原生库)、平台版本问题(是否会升级到 Java) 7 破坏某些东西?),开发人员技能(负责 JNI 集成的“Joe”已经离开了 - 还有谁懂 Java、C++ 和 JNI?)。这些问题的总和(IMO)比初始开发所需的时间更重要。

如果很难,我们很可能会使用 Qt

你为什么不专注于此呢?到目前为止,您还没有提到任何应该首选 Java 的原因。

如果最大的部分是 源代码和调用它的代码你可能会更快地用 C++ 完成这一切。
由于您对 Qt 很满意,因此用户界面不必太担心。

编辑:
我真的看不出 Java 方法有任何优势 - 无论如何,您都必须将源代码的很大一部分移植到其他平台,这会增加包装层的复杂性,并且有更多的依赖性。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top