如何使用: 

Calling Java from C++ with JNI - CodeProject

c++里的 JNI 类型  和 JAVA 类型的映射关系:

JNI Types and Data Structures

Primitive Types and Native Equivalents

Java Type

Native Type

Description

boolean

jboolean

unsigned 8 bits

byte

jbyte

signed 8 bits

char

jchar

unsigned 16 bits

short

jshort

signed 16 bits

int

jint

signed 32 bits

long

jlong

signed 64 bits

float

jfloat

32 bits

double

jdouble

64 bits

void

void

not applicable

JNIEnv 具有 thread affinity ,不可跨线程存储使用,否则 coredump:

The only case that I think fits your question is if you start a Java program, call into a native method, then that native method starts up separate threads. In which case, no, you can't share the JNIEnv pointer, because it's tied to a thread. However, you can use the JNI invocation API to access the Java VM from your C++ thread.

解决方法:https://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/invocation.html

通过attache thread进行 JNIEnv 绑定后无法获得 jclass:

通过系统类加载器进行查找,不会通过应用类加载器进行查找,因此可以加载系统类,但是不能加载非系统类,如自己在java层定义的类会返回NULL。


env->FindClass("xxx/xxx/xxx");//在子线程这样调用是会返回NULL env->FindClass("java/lang/String");//ok

目前本人的解决办法是,在主线程时去findClass然后当做global保存起来


//下边在主线程执行 jclass cls = env->FindClass("xxx/xxx/xxx"); jclass globalCls = static_cast<jclass>(env->NewGlobalRef(cls));//一定要使用NewGlobalRef

这个地方一定要使用NewGlobalRef 将它保存,因为JNI默认的生命周期只有方法体内,这个方法执行完,就会被回收。所以用把它保存成全局引用 然后再不用的时候 调用方法释放掉


env->DeleteGlobalRef(globalCls);

其他参考:

JNI踩过的一些坑 - 简书JNI一些坑 pthread创建的子线程没有 _JNIEnv 因为_JNIEnv 是根据线程相关的,所以pthread创建的native线程必须要调用JavaVMd->Att...


https://www.jianshu.com/p/be89eac99d4e