Embedding JVM into C++ application: 如何正确链接它?

huangapple go评论80阅读模式
英文:

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。

问题

  1. 哪个JVM发行版更适合嵌入到C++中使用?
  2. 如何正确链接和分发所有这些?
英文:

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 created exe

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

  1. What distribution of JVM is better to use for embedding to C++?
  2. How to link and distribute it all properly?

答案1

得分: 3

Solution for Windows:

  1. 编写C++代码,其中包括从JDK引入<jni.h>
  2. 使用WinAPI的LoadLibrary加载${JRE_HOME}/bin/server/jvm.dll
  3. 使用WinAPI的GetProcAddress获取到JNI_CreateJavaVM的指针。
  4. 调用JNI_CreateJavaVM并执行JVM的任何操作。
  5. 编译代码时需要访问${JAVA_HOME}/include/**/*.h
  6. 只需运行已编译的程序。

示例可在此处找到:https://bitbucket.org/kkolyan/j4cpp/src/master/

英文:

Solution for Windows:

  1. write C++ code that:
    1. includes &lt;jni.h&gt; from JDK.
    2. loads "${JRE_HOME}/bin/server/jvm.dll" using LoadLibrary from WinAPI.
    3. gets pointers to JNI_CreateJavaVM using GetProcAddress from WinAPI.
    4. calls JNI_CreateJavaVM and does whatever you want with JVM.
  2. compile it with access to ${JAVA_HOME}/include/**/*.h.
  3. 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.

huangapple
  • 本文由 发表于 2020年8月3日 10:49:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63223094.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定