用 C++ (JNI) 包装 Java 库

Wrapping a Java library with C++ (JNI)

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

由于我不是一个非常有经验的程序员,而且我对 JNI 和多语言编程也没有经验,所以我非常感谢一些关于如何解决这个问题的一般性 pointers/tips/advice。

我特别想知道的事情:

  1. Java 库中的每个 Java class 是否应该映射到关联的 C++ class? IE。在我的 C++ 库中,我会有一个 class 每个调用一个 特定 Java class 的 JVM?还是我会有一个单一的 JVM,通过它可以访问所有内容?执行此操作的最佳方法是什么?为什么?
  2. 执行此操作的基本流程和架构是什么?
  3. 是否有使用调用 API 从 Java 库创建 C++ 库的特定资源?

非常感谢!

I've done this before, but it's not for the faint-hearted especially if your interface between the 2 languages is hard. Debugging can also be a pain in this situation.

To answer your points:

  1. You should start by deciding on what functionality from the Java library you need to access in your C++ program. Is it just a few tasks? Try making a very simple interface from C++ to Java in this case.复杂吗? Then you're gonna have to start mapping Java 类 to C++, and the more you need then the more work it's gonna be.

  2. The end of q1 is sorta q2 really. Your C++ program will start a single JVM which will 运行 as part of your program. When you make calls across the C++ data will be transferred into the JVM, and then the Java code executed, and then the return values transferred back. This incurs a performance cost so calling small functions like add(int,int) through JNI would be more expensive than just doing it in C++.

  3. There's a lot of basic guides you can Google to get started. Just managing to start a basic JVM from C++ and making a call is actually a bit of work since you need to get the paths to the JVM libs correct or it doesn't work (unless they've improved this, it's been years since I tried). So you might want to check that out first before asking more specific questions about JNI and mapping functions.

An alternative option (which may or may-not be possible depending on your library and use-case) is to just write some kind of wrapper service around your library, actually in Java. And then send requests to it via JSON-HTTP or some messaging system.

An even-more alternative option, rewrite whatever the library is doing in C++.

您可以使用 scapix::link::java C++ JNI library to generate C++ headers for any Java code, then easily access this Java code from C++. Here is an 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();
}