java - JNI 不会在 cmake 环境中创建 jclasses

标签 java c++ java-native-interface

所以,我遇到的问题是我有一些代码在通过终端编译时正在运行,但不在 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”作为输出,而它在 cmake 环境中给出“whatever: 0”作为输出。

终端上的编译标志:

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; 

C++ 代码中的 jclass 是指向 _jclass 的指针,因此当您将 whatever 发送到 cout< 时打印的内容 是该指针的值,即它指向的地址。

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

关于java - JNI 不会在 cmake 环境中创建 jclasses,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31319058/

相关文章:

java - 执行线程队列

c++ - 如何在 opengl c++ 中使用多线程添加几个弹跳球

c++ 从标准输入快速读写

java - 如何在 JNI 调用之间保存对象?

Javaquartz 突然停止触发事件

java - 如何清除 Android WebView 的(CSS)访问历史记录?

java - 相当于 javac ant 任务的命令行?

c++ - const 限定符在复制初始化变量时有用吗?

java - JNI MMAP 内存泄漏

java - 通过 native 代码从 jar 访问文件