Я получаю сообщение об ошибке при запуске приложения 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;
}