Я получаю сообщение об ошибке при запуске приложения JNI для Android A/libc﹕ Фатальный сигнал 11 (SIGSEGV) в 0xdeadd00d (код =1), поток 17729

Я получил ошибку, когда я запускаю приложение для Android, в котором я использую функции JNI и код C++. Когда он запустился, я получил сообщение ниже:

Фатальный сигнал 11 (SIGSEGV) в 0xe480001d (код =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 ответа

Решение

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;

Там нет необходимости делать копию.

Здесь есть правильный код:

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;
}
Другие вопросы по тегам