gpt4 book ai didi

安卓 JNI : GetObjectClass crashes with SIGSEGV (not a valid JNI reference)

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:32:12 29 4
gpt4 key购买 nike

我正在尝试创建一个新线程,因此我将 VM 从我的方法初始化(从 Java 调用)传递到我的新线程。在线程中,我调用 AttachCurrentThread 并获取 JNIEnv* env。

稍后,我尝试使用环境调用 GetObjectClass,但它崩溃了。我相信这是因为对象可能未初始化,但我正在尝试调用在包含 native 方法的类中定义的方法。我一直在尝试遵循 http://java.sun.com/docs/books/jni/html/fldmeth.html 的第 4.2 节(开头) .

非常奇怪的事情:我正在使用运行 2.2 的 HTC Dream 进行测试并且以下代码不会崩溃,但是使用运行 2.2.2 的摩托罗拉 Droid 时它会一直崩溃!

这是我的代码:

C++

JNIEXPORT void JNICALL Java_com_device_client_HostConnection_initialize
(JNIEnv * env, jobject obj, jint port) {

JavaVM *vm;
jint result = env->GetJavaVM(&vm);
if (result < 0) {
LOGE("Error using GetJavaVM\n");
exit(-1);
}

struct javaInfo* data = (struct javaInfo*) malloc(sizeof(struct javaInfo));
data->vm = vm;
data->javaObjHost = obj;

pthread_t pth;
pthread_create(&pth, NULL, startServer, (void *) data);
}

新线程:

void *startServer(void* arg) {
jclass cls;
jmethodID mid;
JNIEnv* env = NULL;

struct javaInfo* data = (struct javaInfo*) arg;
JavaVM* vm = data->vm;
jobject javaObjHost = data->javaObjHost;
if (vm == NULL) {
LOGE("VM is null\n");
}
vm->AttachCurrentThread(&env, NULL);

cls = env->GetObjectClass(javaObjHost);
mid = env->GetMethodID(cls, "setStatus", "(Z)V");
if (mid == 0) {
LOGD("ERROR: GetMethodID\n");
exit(-1);
}
env->CallVoidMethod(javaObjHost, mid, false);

行 cls = env->GetObjectClass(javaObjHost);正在崩溃并显示以下输出:

W/dalvikvm( 5827): JNI WARNING: 0x44872da0 is not a valid JNI reference
W/dalvikvm( 5827): in Ldalvik/system/NativeStart;.run ()V (GetObjectClass)
I/dalvikvm( 5827): "Thread-9" prio=5 tid=8 RUNNABLE
I/dalvikvm( 5827): | group="main" sCount=0 dsCount=0 s=N obj=0x448734c8 self=0x229da8
I/dalvikvm( 5827): | sysTid=5834 nice=0 sched=0/0 cgrp=default handle=2265136
I/dalvikvm( 5827): | schedstat=( 885010 3631591 2 )
I/dalvikvm( 5827): at dalvik.system.NativeStart.run(Native Method)
I/dalvikvm( 5827):
E/dalvikvm( 5827): VM aborting
I/DEBUG ( 5511): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 5511): Build fingerprint: 'verizon/voles/sholes/sholes:2.2.2/FRG83G/91102:user/release-keys'
I/DEBUG ( 5511): pid: 5827, tid: 5834 >>> com.device.client <<<
I/DEBUG ( 5511): signal 11 (SIGSEGV), fault addr deadd00d
....

我的java代码:

public class HostConnection {
static {
System.loadLibrary("hostConnection");
}

public void setStatus(boolean bool) {
...
}

public native void initialize(int defaultPort);
}

谁能帮帮我?我想在我的类中调用 setStatus() 方法,而不创建新对象。

编辑:

这是新代码,目前正在崩溃。

JNIEXPORT void JNICALL Java_com_device_client_HostConnection_initialize
(JNIEnv * env, jobject obj, jint port) {
JavaVM *vm;
jint result = env->GetJavaVM(&vm);
if (result < 0) {
LOGE("Error using GetJavaVM\n");
exit(-1);
}

jclass clsLocal = env->GetObjectClass(obj);
if (clsLocal == NULL) {
LOGE("ERROR: Cannot find class HostConnection\n");
exit(-1);
}

jclass hostClass = (jclass) env->NewWeakGlobalRef(clsLocal);
if (hostClass == NULL) {
LOGE("ERROR: Run out of memory for weak global ref\n");
exit(-1);
}

struct javaInfo* data = (struct javaInfo*) malloc(sizeof(struct javaInfo));
data->vm = vm;
data->hostClass = hostClass;

pthread_t pth;
pthread_create(&pth, NULL, startServer, (void *) data);
}

void *startServer(void* arg) {
JNIEnv* env = NULL;
jmethodID mid;
struct fb_var_screeninfo vinfo;
char server[MAXHOSTNAMELEN];

struct javaInfo* data = (struct javaInfo*) arg;
JavaVM* vm = data->vm;
jclass hostClass = data->hostClass;
if (vm == NULL) {
LOGE("VM is null\n");
}
vm->AttachCurrentThread(&env, NULL);

mid = env->GetMethodID(hostClass, "setStatus", "(Z)V");
if (mid == 0) {
LOGD("ERROR: GetMethodID\n");
exit(-1);
}
env->CallVoidMethod(hostClass, mid, false);
}

我遇到以下崩溃:

W/dalvikvm( 7650): JNI WARNING: jclass points to invalid object 0xda88d23f
I/dalvikvm( 7650): "Thread-9" prio=5 tid=8 NATIVE
I/dalvikvm( 7650): | group="main" sCount=0 dsCount=0 s=N obj=0x448734f8 self=0x228a20
I/dalvikvm( 7650): | sysTid=7657 nice=0 sched=0/0 cgrp=default handle=2260192
I/dalvikvm( 7650): | schedstat=( 854493 9155273 2 )
I/dalvikvm( 7650): at dalvik.system.NativeStart.run(Native Method)
I/dalvikvm( 7650):
E/dalvikvm( 7650): VM aborting
I/DEBUG ( 5511): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 5511): Build fingerprint: 'verizon/voles/sholes/sholes:2.2.2/FRG83G/91102:user/release-keys'
I/DEBUG ( 5511): pid: 7650, tid: 7657 >>> com.device.client <<<
I/DEBUG ( 5511): signal 11 (SIGSEGV), fault addr deadd00d

我知道它在 GetMethodID() 上崩溃。我真的不知道为什么。非常感谢任何帮助。

非常感谢。

最佳答案

您从Java_com_device_client_HostConnection_initialize 获取对象 作为本地引用,然后将其传递给javaInfo 结构中的新线程。

局部引用只在当前线程有效,与JNIEnv*指针一样。

因此,当您从新线程中的结构中获取它时,您对该对象的引用无效,这就解释了崩溃。

尝试使用 JNIEnv 中的 NewWeakGlobalRef 方法在 Java_com_device_client_HostConnection_initialize 方法中获取 WeakGlobal 引用。

阅读 JNI 文档的第五章以了解本地、全局和弱全局引用之间的区别。

关于安卓 JNI : GetObjectClass crashes with SIGSEGV (not a valid JNI reference),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7864614/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com