简体   繁体   English

JNI_CreateJavaVM 函数方法不起作用,无法调试

[英]JNI_CreateJavaVM function method does not work and cannot be debugged

JNI_CreateJavaVM function method does not work and cannot be debugged. JNI_CreateJavaVM 函数方法不起作用,无法调试。

  • The development environment is win10 x64, jdk version is 1.8开发环境为win10 x64,jdk版本为1.8

  • Visual studio 2017 Community Edition Writing a C++ project Visual Studio 2017 Community Edition 编写 C++ 项目


I am learning about JNI.我正在学习 JNI。 I am trying to run The Invocation API .我正在尝试运行The Invocation API The following URL is an example of the official website documentation.以下网址为官网文档示例。
Click here !点击这里

I built the project and added a project dependency that contains jvm.lib.我构建了项目并添加了一个包含 jvm.lib 的项目依赖项。 And I put jvm.dll in the project directory.我把 jvm.dll 放在项目目录中。 I successfully run this program.我成功运行了这个程序。

Main.test() is a method of print hello world . Main.test()是一种打印hello world的方法。 But the program exits when executing JNI_CreateJavaVM, the console shows that the return value is 1.但是程序在执行JNI_CreateJavaVM时退出,控制台显示返回值为1。

I can't get into debugging, I don't know what happened.我无法进入调试,我不知道发生了什么。

#include <jni.h>


int main() {
    printf("begin..........\n");
    JavaVM *jvm;       /* denotes a Java VM */
    JNIEnv *env;       /* pointer to native method interface */
    JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */
    JavaVMOption* options = new JavaVMOption[1];
    char optionString[] = "-Djava.class.path =D:/Program Files/Java/jdk1.8.0_191/lib/";
    options[0].optionString = optionString;
    vm_args.version = JNI_VERSION_1_8;
    vm_args.nOptions = 1;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = false;
    /* load and initialize a Java VM, return a JNI interface
     * pointer in env */

    int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    printf("result=%d", res);
    delete options;
    /* invoke the Main.test method using the JNI */
    jclass cls = env->FindClass("Main");
    jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");
    env->CallStaticVoidMethod(cls, mid, 100);
    /* We are done. */
    jvm->DestroyJavaVM();
    return 0;
}

I expect this jvm can be called, but it is forced to exit when the program is executed to `int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);我期望这个jvm可以被调用,但是当程序执行到`int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); Where am I wrong?我哪里错了? Why is it not working?为什么它不起作用?

Exit screenshot enter image description here退出截图在此输入图片说明

jvm.dll location enter image description here jvm.dll 位置在这里输入图片描述

jvm.lib linker additional library directories enter image description here jvm.lib 链接器附加库目录在此处输入图像描述

jvm.lib linker additional Dependencies enter image description here jvm.lib 链接器附加依赖项在此处输入图像描述

Classpath类路径

There is a space between key and equal sign.键和等号之间有一个空格。 The space must be removed.必须删除该空间。

char optionString[] = "-Djava.class.path =D:/Program Files/Java/jdk1.8.0_191/lib/";

Classpath value类路径值

The java.class.path value must point to the base directory where your compiled .class files are located. java.class.path 值必须指向已编译的 .class 文件所在的基本目录。

It looks like you're not using a package name, then it's the directory where Main.class is located, so probably it should look something like this:看起来你没有使用包名,那么它是 Main.class 所在的目录,所以它可能应该是这样的:

char optionString[] = "-Djava.class.path=c:/Users/name/MyJavaPrograms/classes";

Access violation访问冲突

SEGV (or exception 0xC0000005) is also generated intentionally on JVM startup to verify certain CPU/OS features. SEGV(或异常 0xC0000005)也在 JVM 启动时有意生成,以验证某些 CPU/OS 功能。

see this fine answer: https://stackoverflow.com/a/36258856看到这个很好的答案: https : //stackoverflow.com/a/36258856

In Visual Studio, when the exception dialog is shown, simply turn off that it breaks there.在 Visual Studio 中,当显示异常对话框时,只需将其关闭即可。 This will prevent you from seeing it again the next time you start the program again.这将防止您下次再次启动程序时再次看到它。

Java爪哇

Just for the sake of completeness: the Java method should look like this:为了完整起见:Java 方法应如下所示:

public class Main {

public static void test(int num) {
    System.out.println("Java: test called with '" + num + "'");
}

...

Visual Studio Configuration Visual Studio 配置

The jvm.dll needs to be found.需要找到 jvm.dll。 In Visual Studio under Configuration Properties/Debugging/Environment add PATH=%PATH%;<path-to-jdk>\\bin\\server在 Visual Studio 下的 Configuration Properties/Debugging/Environment 添加 PATH=%PATH%;<path-to-jdk>\\bin\\server

For later deployment you could think about putting the whole JRE into a subfolder of your application and reference it with a relative path.对于以后的部署,您可以考虑将整个 JRE 放入应用程序的子文件夹中,并使用相对路径引用它。

Demo演示

Finally a brief demo (added a \\n here printf("result=%d\\n", res); to have a separate line):最后是一个简短的演示(在printf("result=%d\\n", res);添加了一个 \\n 以单独一行):

演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM