java-c++绑定:如何在不崩溃的情况下获取存储jobject的对象类?

iezvtpos  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(327)

目标:
绑定cBuf 到java类 Bug 让cBuf 调用java的方法 Bug 不要崩溃(怎么做?)
目的:
路线 std::cout android应用程序中的文本字段
绑定c++ stringbuf 到java OutputStream java Bug :
java的构造函数 Bug 将构造一个c++ Buf java Bug 通过其 JNIEnv 以及 jobject 到c++ Buf .
java Bug 包含指向c的指针 Buf java Bugbeep() 方法调用cBuf::beep() c++ Buf :
存储 JNIEnv 以及 jobject 来自java
Bug Buf::beep() 当它试图找到
jobject 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();
    }
}
yjghlzjz

yjghlzjz1#

你可以添加try{}catch{}。有了这些,你就可以停止破坏你的软件并顺利运行

相关问题