JavaC++绑定:如何在不崩溃的情况下获取存储作业对象的ObjectClass

Java-C++ binding: How to GetOjectClass of a stored jobject without crashing?

本文关键字:获取 情况下 存储 作业 ObjectClass 对象 崩溃 绑定 JavaC++      更新时间:2024-09-29

目标:

  • 将C++类Buf绑定到Java类Bug
  • 让C++Buf调用JavaBug的一个方法
  • 不要崩溃(怎么崩溃?(

用途:

  • std::cout路由到安卓应用程序中的文本字段
  • 将C++stringbuf绑定到JavaOutputStream

JavaBug:

  • JavaBug的构造函数将构造C++Buf
  • JavaBug将其JNIEnvjobject传递给C++Buf
  • JavaBug包含指向C++Buf的指针
  • JavaBugbeep()方法调用C++Buf::beep()

C++Buf:

  • 存储JavaBug中的JNIEnvjobject
  • Buf::beep()在尝试查找jobject的java类时崩溃

MainActivity.java:

  • 使用Native C++ template创建新项目
  • 安卓工作室
  • 镗孔

错误:

A/org.so.buggy: runtime.cc:663] 
JNI DETECTED ERROR IN APPLICATION: 
use of invalid jobject 0xffbdfb78 from 
void org.so.buggy.Bug.beep()
--------- beginning of crash
A/libc: Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid
6865 (org.so.buggy), pid 6865 (org.so.buggy)

Bug.java:

package org.so.buggy;
// Wrapper for the C++ Buf
public class Bug {
public Bug() {
init();
}
public native void beep();  // <- Crash here
private native void init(); // Construct Buf
private long nativeHandle;  // Pointer to Buf
}

native-lib.cpp:

#include <jni.h>
class MyBuf {
public:
MyBuf(JNIEnv *env, jobject obj) :
_env(env), _obj(obj) {
_env->GetObjectClass(_obj); // no crash
};
void beep() {
_env->GetObjectClass(_obj); // crash!
}
private:
JNIEnv *_env;
jobject _obj;
};
// -- Manage the Java object's connection -- //
// -- to the C++ object (Buf)             -- //
jfieldID getHandleField(JNIEnv *env, jobject obj) {
jclass c = env->GetObjectClass(obj);
return env->GetFieldID(c, "nativeHandle", "J");
}
MyBuf *get_handle(JNIEnv *env, jobject obj) {
// Get pointer to C++ Buf from the Java object
jlong handle = env->GetLongField(obj, getHandleField(env, obj));
return reinterpret_cast<MyBuf *>(handle);
}
void set_handle(JNIEnv *env, jobject obj, MyBuf *instance) {
// Java object's handle = pointer to C++ Buf
jlong handle = reinterpret_cast<jlong>(instance);
env->SetLongField(obj, getHandleField(env, obj), handle);
}
extern "C" void
Java_org_so_buggy_Bug_init(JNIEnv *env, jobject obj) {
auto *instance = new MyBuf(env, obj);
set_handle(env, obj, instance);
}
// ---- The beep that crashes the app ---- //
extern "C" void
Java_org_so_buggy_Bug_beep(JNIEnv *env, jobject obj) {
auto *p = get_handle(env, obj);
p->beep();
}

主要活动.java

package org.so.buggy;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
static {System.loadLibrary("native-lib");}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bug b = new Bug();
b.beep();
}
}

U可以添加Try{}catch{}.有了这些,你可以停止崩溃你的软件并顺利运行

相关文章: