JNI 不会在 cmake 环境中创建 jclasses

JNI doesn't create jclasses in a cmake-environment

所以,我遇到的问题是我有一些代码是 运行 当通过终端编译时,但不是在 cmake 环境中..

我想我可以将我的错误减少到以下几点:

int main(int argc, char **argv) {

    jclass whatever;
    std::cout << "whatever: " << whatever << std::endl; 
    JavaVM * jvm;
    JNIEnv* env = create_vm(&jvm);
    invoke_class( env );
}

给出 "whatever: 0x7fff2fbfb820" 作为输出,而它给出 "whatever: 0" 作为 cmake 环境中的输出。

终端上的编译标志:

g++ -g -I/usr/lib/jvm/default-java/include -I/usr/lib/jvm/default-java/include/linux -L/usr/bin/java -L/usr/lib/jvm/default-java/jre/lib/amd64/server/ CreateJVM.cpp -ljvm

大体代码如下:

#include <stdio.h>
#include <jni.h>
#include <iostream>

JNIEnv* create_vm(JavaVM ** jvm) {
    JNIEnv* env;
    JavaVMInitArgs vm_args;
    JavaVMOption options;
    vm_args.version = JNI_VERSION_1_6;
    vm_args.nOptions = 1;
    options.optionString = "-Djava.class.path=.";
    vm_args.options = &options;
    vm_args.ignoreUnrecognized = JNI_FALSE;

    int ret = JNI_CreateJavaVM(jvm, (void **)&env, &vm_args);
    if(ret < 0)
        printf("\nUnable to Launch JVM\n");
    return env;
}
void call_testing2(JNIEnv* env, jclass hClass){
    jmethodID testing2Method;
    jfloatArray floats = env->NewFloatArray(1);
    jintArray test = env->NewIntArray(1);
    jfloat *fl = env->GetFloatArrayElements(floats, NULL);
    fl[0] = 5.893241874931;
    env->ReleaseFloatArrayElements(floats, fl, 0);
    jint *in = env->GetIntArrayElements(test, NULL);
    in[0] = 42;
    env->ReleaseIntArrayElements(test, in, 0);
    testing2Method = env->GetMethodID(hClass, "testing2", "([F[I)I");
    int x = env->CallStaticIntMethod(hClass, testing2Method, floats, test);
}
void invoke_class(JNIEnv* env) {
    jclass helloWorldClass;
    helloWorldClass = env->FindClass("InvocationHelloWorld");
    call_testing2(env, helloWorldClass);
}

jclass "helloWorldClass" 也会出现同样的问题。 我在 cmake 文件中包含了 jni 路径并链接了 jni 库。这里出了什么问题?

jclass whatever;
std::cout << "whatever: " << whatever << std::endl; 

A jclass 在 C++ 代码中是一个指向 _jclass 的指针,所以当你将 whatever 发送到 cout 时打印的是该指针的值,即它指向的地址。

当您尝试在代码中打印 whatever 时,您仍然没有初始化它,并且在没有初始化器的情况下声明的局部非静态变量将具有不确定的值。因此,在初始化 whatever 之前打印它时(例如,通过调用 FindClass 为它分配 return 值),你可以得到任何结果,并且 "anything"在某些情况下恰好是 0x7fff2fbfb820,在某些情况下恰好是 0