将 JVM 嵌入到 C++ 应用程序中:如何正确 link 它?
Embedding JVM into C++ application: How to link it properly?
目标
比方说,我们有一个大型 C++ 应用程序,它执行一些大的事情,这些事情很适合使用 C++ 来完成。但是,有很多逻辑,我们更愿意在 JVM 上 运行。
问题
为了测试上述方法,我使用 CLion 创建了 small C++ project。
场景是:
Build(由 CMake 自动执行):
- link 代码段
$JAVA_HOME/lib/jvm.lib
- 将所有 DLL 从
$JAVA_HOME
复制到刚创建的目录 exe
运行:
- 创建嵌入式 JVM
- 调用此 JVM 托管的静态方法
我尝试了 Visual Studio 2019 Community 和 MinGW64 (x86_64-8.1.0-posix-seh-rt_v6-rev0) 工具链,结果相同。
我使用 OpenJDK (jdk-14.0.2) 获得的最佳结果:
Error occurred during initialization of VM
Failed setting boot class path.
Oracle JDK 1.8 出现了一些不同的故障:
Error occurred during initialization of VM
Unable to load native library: Can't find dependent libraries
我还尝试了 ojdkbuild 的不同版本,我得到的最好的版本是 env->FindClass
调用时的 SEGFAULT。
问题
- 哪种 JVM 发行版更适合嵌入到 C++ 中?
- 如何link并正确分配?
What distribution of JVM is better to use for embedding to C++?
嵌入没有区别,因为其中很大一部分只是 OpenJDK 代码,稍作调整。
How to link and distribute it all properly?
copy all DLLs from $JAVA_HOME to the directory with just created exe
这行不通,因为 JVM 需要更多。
您将不得不分发 JDK 的一部分,仅 DLL 是不够的,因为缺少所有 class 库。您可以尝试使用 jimage
构建较小的图像。这将包括所有相关部分(=JVM、类库、本机库)
link 对抗 JVM,你的做法是正确的。
Windows 的解决方案:
- 编写 C++ 代码:
- 包括来自 JDK.
的 <jni.h>
- 使用
LoadLibrary
从 WinAPI 加载“${JRE_HOME}/bin/server/jvm.dll”。
- 使用来自 WinAPI 的
GetProcAddress
获取指向 JNI_CreateJavaVM
的指针。
- 调用
JNI_CreateJavaVM
并使用 JVM 做任何您想做的事。
- 编译它并访问
${JAVA_HOME}/include/**/*.h
。
- 只是运行编译的程序。
目标
比方说,我们有一个大型 C++ 应用程序,它执行一些大的事情,这些事情很适合使用 C++ 来完成。但是,有很多逻辑,我们更愿意在 JVM 上 运行。
问题
为了测试上述方法,我使用 CLion 创建了 small C++ project。 场景是:
Build(由 CMake 自动执行):
- link 代码段
$JAVA_HOME/lib/jvm.lib
- 将所有 DLL 从
$JAVA_HOME
复制到刚创建的目录exe
运行:
- 创建嵌入式 JVM
- 调用此 JVM 托管的静态方法
我尝试了 Visual Studio 2019 Community 和 MinGW64 (x86_64-8.1.0-posix-seh-rt_v6-rev0) 工具链,结果相同。
我使用 OpenJDK (jdk-14.0.2) 获得的最佳结果:
Error occurred during initialization of VM
Failed setting boot class path.
Oracle JDK 1.8 出现了一些不同的故障:
Error occurred during initialization of VM
Unable to load native library: Can't find dependent libraries
我还尝试了 ojdkbuild 的不同版本,我得到的最好的版本是 env->FindClass
调用时的 SEGFAULT。
问题
- 哪种 JVM 发行版更适合嵌入到 C++ 中?
- 如何link并正确分配?
What distribution of JVM is better to use for embedding to C++?
嵌入没有区别,因为其中很大一部分只是 OpenJDK 代码,稍作调整。
How to link and distribute it all properly?
copy all DLLs from $JAVA_HOME to the directory with just created exe
这行不通,因为 JVM 需要更多。
您将不得不分发 JDK 的一部分,仅 DLL 是不够的,因为缺少所有 class 库。您可以尝试使用 jimage
构建较小的图像。这将包括所有相关部分(=JVM、类库、本机库)
link 对抗 JVM,你的做法是正确的。
Windows 的解决方案:
- 编写 C++ 代码:
- 包括来自 JDK. 的
- 使用
LoadLibrary
从 WinAPI 加载“${JRE_HOME}/bin/server/jvm.dll”。 - 使用来自 WinAPI 的
GetProcAddress
获取指向JNI_CreateJavaVM
的指针。 - 调用
JNI_CreateJavaVM
并使用 JVM 做任何您想做的事。
<jni.h>
- 编译它并访问
${JAVA_HOME}/include/**/*.h
。 - 只是运行编译的程序。