英文:
Embedding JVM into C++ application: How to link it properly?
问题
目标
假设我们有一个大型的C++应用程序,其中有一些最好使用C++来完成的大型任务。但是,有很多逻辑,我们更喜欢在JVM上运行。
问题
为了测试上述描述的方法,我使用CLion创建了一个小的C++项目。
场景如下:
构建(由CMake自动化):
- 使用
$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)获得了最佳结果:
初始化VM时发生错误
无法设置引导类路径。
Oracle JDK 1.8显示了稍微不同的错误:
初始化VM时发生错误
无法加载本机库:找不到依赖的库
我还尝试了来自ojdkbuild的不同版本,最好的结果是在env->FindClass
调用时出现SEGFAULT。
问题
- 哪个JVM发行版更适合嵌入到C++中使用?
- 如何正确链接和分发所有这些?
英文:
Goal
Let's say, we have a large C++ application that does some large things, that are good to be done using C++. But, there are a plenty of logic, that we'd prefer to run on JVM.
Issue
To test approach described above, I created small C++ project using CLion.
Scenario is:
Build (automated by CMake):
- link code snippet with
$JAVA_HOME/lib/jvm.lib
- copy all DLLs from
$JAVA_HOME
to the directory with just createdexe
Run:
- create embedded JVM
- invoke static method hosted by this JVM
I tried Visual Studio 2019 Community and MinGW64 (x86_64-8.1.0-posix-seh-rt_v6-rev0) toolchains and both led to identical results.
The best results I've got with OpenJDK (jdk-14.0.2):
Error occurred during initialization of VM
Failed setting boot class path.
Oracle JDK 1.8 has shown a bit different failure:
Error occurred during initialization of VM
Unable to load native library: Can't find dependent libraries
I also tried different versions from ojdkbuild and the best I get is SEGFAULT at the env->FindClass
invocation.
Questions
- What distribution of JVM is better to use for embedding to C++?
- How to link and distribute it all properly?
答案1
得分: 3
Solution for Windows:
- 编写C++代码,其中包括从JDK引入
<jni.h>
。 - 使用WinAPI的
LoadLibrary
加载${JRE_HOME}/bin/server/jvm.dll
。 - 使用WinAPI的
GetProcAddress
获取到JNI_CreateJavaVM
的指针。 - 调用
JNI_CreateJavaVM
并执行JVM的任何操作。 - 编译代码时需要访问
${JAVA_HOME}/include/**/*.h
。 - 只需运行已编译的程序。
示例可在此处找到:https://bitbucket.org/kkolyan/j4cpp/src/master/
英文:
Solution for Windows:
- write C++ code that:
- includes
<jni.h>
from JDK. - loads "${JRE_HOME}/bin/server/jvm.dll" using
LoadLibrary
from WinAPI. - gets pointers to
JNI_CreateJavaVM
usingGetProcAddress
from WinAPI. - calls
JNI_CreateJavaVM
and does whatever you want with JVM.
- includes
- compile it with access to
${JAVA_HOME}/include/**/*.h
. - just run compiled program.
Working example here: https://bitbucket.org/kkolyan/j4cpp/src/master/
答案2
得分: 1
Here is the translation:
"哪种JVM分发版本更适合嵌入到C++中使用?
在嵌入方面没有区别,因为它们的大部分只是带有小改进的OpenJDK代码。
如何正确链接和分发它?
将$JAVA_HOME中的所有DLL文件复制到刚创建的exe文件所在的目录中。
这不会起作用,因为JVM需要更多内容。
您将不得不分发JDK的一部分,仅DLL文件是不够的,因为所有类库都不包含在内。您可以尝试使用jimage
构建一个较小的镜像。这将包括所有相关部分(=JVM、类库、本地库)。
要针对JVM进行链接,您应该以正确的方式进行。"
英文:
>What distribution of JVM is better to use for embedding to C++?
There is no difference in embedding, as a big part of them is just OpenJDK code with small tweaks.
>How to link and distribute it all properly?
>copy all DLLs from $JAVA_HOME to the directory with just created exe
This won't work, as the JVM needs a lot more.
You will have to distribute a part of the JDK, only the DLLs is not enough, as all class libraries are missing. You could try building a smaller image with jimage
. This will include all relevant parts (=JVM,Classlibraries,native libraries)
To link against the JVM, you do it the right way.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论