我运行JNI Android应用时收到错误消息 A/libc:在0xdeadd00d处发生致命信号11(SIGSEGV) (code=1),线程17729。

5
当我在运行使用JNI函数和c++代码的安卓应用程序时,出现了错误。运行时,我看到了以下信息:
致命信号11(SIGSEGV)位于0xe480001d(code=1),线程5465
这是我的代码:
JNIEXPORT jstring JNICALL Java_ir_bassir_ndktest4_MainActivity_getName
(JNIEnv *env, jobject obj){

  jclass cls = (*env)->GetObjectClass(env, obj);
  jmethodID mid = (*env)->GetStaticMethodID(env, cls, "testJava", "([Ljava/lang/String)[Ljava/lang/String");

  jstring plainText = (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI  2222 ");
  jstring result = (*env)->CallStaticObjectMethod(env, cls, mid, plainText);

  return (*env)->NewStringUTF(env, plainText);
}

在Java方面:

public class MainActivity extends ActionBarActivity {

    public native String getName();

    public static String testJava(String txt){
        Log.d("BP","call back to java method");
        String result = txt + "its added in JAVA";
        return result;
    }

    static{
        System.loadLibrary("HelloJNI");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String name = getName();

        Log.d("BP",name);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
2个回答

3
这段代码的JNI部分是用C而不是C++编写的,C对指针强制转换的处理较为宽松,这也是问题的一部分。你的代码在以下两行中出现了错误:
jstring plainText = (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI  2222 ");
return (*env)->NewStringUTF(env, plainText);

由于NewStringUTF具有签名

jstring NewStringUTF(JNIEnv *env, const char *bytes);

这意味着这个调用已经失效了:
//                        vvvvvvvvv--- plainText is not of the right type!
(*env)->NewStringUTF(env, plainText)

这段代码中,C编译器可以接受它,因为jstring是指针类型(C++编译器则不行),所以plainText将被解释为char const *,从而导致一些愚蠢的事情发生。

无论如何,我猜你想表达的是

return result;

...但是如果你想返回plainText(纯文本),请直接说明

return plainText;

不需要复制。


非常感谢您的回复,Wintermute。但我的代码还有另一个错误,我已经纠正并放在了下一个答案中。 - bassir pechaz

1
这里有一段正确的代码:


JNIEXPORT jstring JNICALL Java_ir_bassir_ndktest4_MainActivity_getName  (JNIEnv *env, jobject obj) {
    jclass cls = (*env)->GetObjectClass(env, obj);
    jmethodID mid = (*env)->GetStaticMethodID(env, cls, "testJava", "(Ljava/lang/String;)Ljava/lang/String;");

    jstring plainText = (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI  2222 ");
    jstring result = (*env)->CallStaticObjectMethod(env, cls, mid, plainText);
    return result;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接