C++通过JNI调用Java方法需先获取JNIEnv,再通过GetObjectClass/FindClass、GetMethodID/GetStaticMethodID、CallObjectMethod/CallStaticObjectMethod等完成调用,严格处理签名、异常检查及局部引用释放。

在C++中通过JNI调用Java方法,核心是获取Java对象或类的引用,再通过JNIEnv提供的函数(如GetMethodID、CallObjectMethod等)完成调用。关键在于正确获取类、方法ID和参数处理,尤其注意局部/全局引用管理和异常检查。
获取JNIEnv指针与JVM环境
Native代码必须运行在JVM已启动的上下文中。常见方式有:
- 从Java层回调进入C++(如声明
native方法),此时JNIEnv由JVM自动传入,可直接使用; - 在独立C++程序中主动Attach到JVM(需持有JavaVM*指针),调用
GetEnv或AttachCurrentThread获取JNIEnv; - Detach前必须调用
DetachCurrentThread(仅对Attach过的线程)。
调用Java实例方法(非静态)
假设Java类为com.example.Utils,含方法public String format(String s, int n),且已有该类实例jobject obj:
// 1. 获取类引用(可缓存)
jclass cls = env->GetObjectClass(obj);
if (!cls) { /* 处理异常 */ }
<p>// 2. 获取方法ID(签名需严格匹配)
// "format" 是方法名;"(Ljava/lang/String;I)Ljava/lang/String;" 是签名
jmethodID mid = env->GetMethodID(cls, "format", "(Ljava/lang/String;I)Ljava/lang/String;");
if (!mid) { /<em> 方法未找到或异常 </em>/ }</p><p>// 3. 构造参数:创建Java字符串
jstring jstr = env->NewStringUTF("hello");
if (!jstr) { /<em> 内存不足 </em>/ }</p><p>// 4. 调用方法
jstring result = (jstring)env->CallObjectMethod(obj, mid, jstr, 123);</p><p>// 5. 使用结果(如转为C字符串)
const char* cstr = env->GetStringUTFChars(result, nullptr);
if (cstr) {
printf("Result: %s\n", cstr);
env->ReleaseStringUTFChars(result, cstr); // 必须释放
}</p><p>// 6. 清理局部引用(避免引用泄漏)
env->DeleteLocalRef(jstr);
env->DeleteLocalRef(result);
env->DeleteLocalRef(cls);
登录后复制
调用Java静态方法
无需Java对象实例,改用GetStaticMethodID和CallStaticXXXMethod:
立即学习“Java免费学习笔记(深入)”;
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~