JavaC++绑定:如何在不崩溃的情况下获取存储作业对象的ObjectClass
Java-C++ binding: How to GetOjectClass of a stored jobject without crashing?
目标:
- 将C++类
Buf
绑定到Java类Bug
- 让C++
Buf
调用JavaBug
的一个方法 - 不要崩溃(怎么崩溃?(
用途:
- 将
std::cout
路由到安卓应用程序中的文本字段 - 将C++
stringbuf
绑定到JavaOutputStream
JavaBug
:
- Java
Bug
的构造函数将构造C++Buf
- Java
Bug
将其JNIEnv
和jobject
传递给C++Buf
- Java
Bug
包含指向C++Buf
的指针 - Java
Bug
的beep()
方法调用C++Buf::beep()
C++Buf
:
- 存储Java
Bug
中的JNIEnv
和jobject
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{}.有了这些,你可以停止崩溃你的软件并顺利运行
相关文章:
- 如何在没有实例的情况下获取非静态方法的类型?
- 如何在不等待检索的情况下获取C++中的内存位置?
- 如何在没有硬编码的情况下以C++为单位获取类数组的长度?
- 如何在不为其声明变量的情况下获取和使用常量值的地址?
- 在不使用模板的情况下获取 std::array 引用
- 在确定有实现的情况下获取HTTP 501未实现
- 如何在给定时钟偏移的情况下正确获取时间
- 如何从 std::optional 中获取 QByteArray<QByteArray>,并在没有其他 malloc 的情况下保留 std::nullopt?
- C++11 - 获取编译时的所有类变量,并在没有 Boost 的情况下为它们调用方法
- 如何将左值传递给函数,仅在没有模板的情况下获取右值
- 如何在不创建实例的情况下获取类的方法成员的类型?
- 如何在没有作弊引擎的情况下从其他应用程序获取指针地址?
- 如何在不使用返回的情况下从函数获取变量的地址(指针)
- 如何在不包含 Windows.h 的情况下获取 IsDebuggerPresent 的声明
- 如何在没有.app的情况下,在 macOS 上使用 qmake 获取二进制文件
- <int> 在不破坏堆栈的情况下获取 C++ 中的堆栈总和
- 在不使用API的情况下,如何在Windows中获取过程信息
- 如何在不引起实例化的情况下获取功能模板的签名
- 如何在不定义其他 fonction getValue() 的情况下获取私有值
- 如何在不获取所有html的情况下获取QTextEdit的html标签?