用C ++(JNI)包装Java库

时间:2018-10-14 21:39:21

标签: java c++ java-native-interface libraries jniwrapper

我有一个用C ++编写的大型程序,需要使用特定的Java库。理想情况下,我想创建一个包装该现有Java代码的等效C ++库。因此,我一直在研究JNI调用API。

由于我不是一个非常有经验的程序员,而且我对JNI和多语言编程也没有经验,因此,我将非常感谢一些有关如何解决此问题的通用指针/技巧/建议。

我特别想知道的事情:

  1. Java库中的每个Java类都应映射到关联的C ++吗? 类?即在我的C ++库中,我是否会有一个类分别调用一个 特定Java类的JVM?还是我将拥有一个用于访问所有内容的单一JVM?最好的方法是什么?为什么?
  2. 执行此操作的基本过程和体系结构是什么?
  3. 是否有用于使用调用API从Java库创建C ++库的特定资源?

非常感谢!

2 个答案:

答案 0 :(得分:1)

我以前已经做过这件事,但这不是为胆小者准备的,特别是如果您很难使用两种语言之间的界面。在这种情况下,调试也可能会很痛苦。

回答您的观点:

  1. 您应该首先确定需要在C ++程序中访问Java库中的哪些功能。这只是几个任务吗?在这种情况下,请尝试建立一个从C ++到Java的非常简单的接口。复杂吗?然后,您将不得不开始将Java类映射到C ++,并且您需要的越多,它将需要的工作就越多。

  2. q1的末尾实际上是q2。您的C ++程序将启动一个JVM,它将作为程序的一部分运行。当您跨C ++进行调用时,数据将被传输到JVM中,然后执行Java代码,然后将返回值传输回去。这会产生性能成本,因此通过JNI调用add(int,int)之类的小功能会比仅使用C ++花费更多。

  3. 有很多基本指南,您可以通过Google入门。仅仅设法从C ++启动一个基本的JVM并进行调用实际上有点工作,因为您需要正确获取JVM库的路径或它不起作用(除非他们对此进行了改进,距我已经有好几年了。尝试)。因此,您可能需要先检查一下,然后再询问有关JNI和映射函数的更具体的问题。

另一种选择(取决于您的库和用例,可能会或可能不会)是实际上使用Java在库周围编写某种包装服务。然后通过JSON-HTTP或某些消息传递系统向其发送请求。

一个甚至更多的选择,重写库在C ++中所做的任何事情。

答案 1 :(得分:0)

您可以使用scapix::link::java C ++ JNI库为任何Java代码生成C ++标头,然后轻松地从C ++访问此Java代码。这是example

#include <scapix/java_api/java/lang/System.h>
#include <scapix/java_api/java/util/Locale.h>
#include <scapix/java_api/java/text/DateFormatSymbols.h>

using namespace scapix::link::java;
using namespace scapix::java_api;

void test1()
{
    // C++ objects are automatically converted to and from corresponding Java types.
    // This works for any type supported by scapix::link::java::convert() interface,
    // which supports many STL types and can be extended for your own types.

    std::string version = java::lang::System::getProperty("java.version");
    std::vector<std::string> languages = java::util::Locale::getISOLanguages();
    std::vector<std::vector<std::string>> zone_strings = java::text::DateFormatSymbols::getInstance()->getZoneStrings();
    std::map<std::string, std::string> properties = java::lang::System::getProperties();
}