JNI在cmake-environment

时间:2015-07-09 13:32:16

标签: 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 );
}

给出&#34;无论如何:0x7fff2fbfb820&#34;作为输出,它给出了&#34;无论如何:0&#34;作为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&#34; helloWorldClass&#34;出现同样的问题。 我已经包含了jni-path并将jni-libraries链接到了cmake文件中。这里出了什么问题?

1 个答案:

答案 0 :(得分:2)

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

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

当您尝试在代码中打印whatever时,您仍然无法初始化它,并且在没有初始化程序的情况下声明的本地非静态变量将具有不确定的值。因此,在您初始化之前打印whatever(例如,通过将来自FindClass的通话中的返回值分配给它),您可以得到任何结果,并且&#34;任何内容&#34} ;恰好在某些情况下为0x7fff2fbfb820,在某些情况下为0