【问题标题】:Android ndk Fatal signal code=1Android ndk 致命信号代码=1
【发布时间】:2014-04-17 08:19:16
【问题描述】:

我正在尝试从 c++ 调用 Java 方法。

C++

JNIEXPORT void JNICALL Java_ru_sploid_platerecog_RecogActivity_FindFeatures(JNIEnv* env, jobject job, jlong addr_rgba)
{
Mat& m_rgba = *(Mat*)addr_rgba;

try
{
    const pair< string, int > fn = read_number( m_rgba, 10 );
    jclass clazz = env->FindClass("ru/sploid/platerecog/RecogActivity");
    jmethodID meth=env->GetMethodID(clazz,"onGetNumber","(Ljava/lang/String;)V");
    env->CallVoidMethod(job,meth,fn.first.data());
//  cv::putText( m_rgba, fn.first.empty() ? string( "not found" ) : fn.first, cv::Point( 20, 100 ), CV_FONT_HERSHEY_PLAIN, 2.0, cv::Scalar( 255, 0, 0, 0 ) );
}
catch ( const std::exception& e )
{
    cout << "Catch exception: " << e.what() << endl;
    cv::putText( m_rgba, "Exception", cv::Point( 20, 100 ), CV_FONT_HERSHEY_PLAIN, 2.0, cv::Scalar( 255, 0, 0, 0 ) );

}
}

Java:

public void onGetNumber(String plate){
    plat=plate;
    runOnUiThread(new Runnable() {

        @Override
        public void run() {
            if (plat!=null)
                Toast.makeText(getApplicationContext(), plat, Toast.LENGTH_LONG).show();
            else
                Toast.makeText(getApplicationContext(), "((", Toast.LENGTH_LONG).show();
        }
    });

}

应用关闭 03-12 23:33:29.172: A/libc(21987): Fatal signal 11 (SIGSEGV) at 0x323030b9 (code=1)

我认为我在 C++ 中有错误。谢谢

【问题讨论】:

  • 发布完整的堆栈跟踪,或者至少发布更多。
  • @ChrisStratton 不再有趣。只有简单的 openCV 消息
  • 然后查找并禁用阻止您获取堆栈跟踪的任何异常处理程序。或者在ndk-gdb下运行。或者在您的本机代码中添加一些日志记录。但是让人们猜测错误位置是不合理的。
  • @ChrisStratton 我会做的

标签: java android c++ android-ndk


【解决方案1】:

您的代码中没有验证。我希望这是为了这篇文章而删减的。您应该检查clazzmethod 是否有效。

无论如何,如果我没有遗漏什么,您可以将 char* 传递给 Java 方法而不是 jstring。您必须使用 JNI NewStringUTF() 或类似方法将 fn.first 转换为 Java 字符串。

【讨论】:

  • 谢谢,你是对的。我需要使用 NewStringUTF()
【解决方案2】:

看起来您将char* 传递给CallVoidMethod() - 这是错误的,您需要传递jstring 对象。要围绕 char* 创建 jstring,请使用 env-&gt;NewStringUTF()

换句话说,这条线是这样的:

env->CallVoidMethod(job,meth,env->NewStringUTF(fn.first.data()));

假设字符串确实是 UTF-8。如果它在另一个代码页中(例如 CP1251)并且可能包含非 ASCII 字符,则需要转换。

【讨论】:

  • 谢谢。它有帮助。你太棒了)
  • Op,建议你也看看 DeleteLocalRef。在这里泄漏可能没问题,但即使如此,允许的本地引用数量也非常低,我认为是 250 左右,所以最好在调用 java 方法后删除。
  • 最多 512 个 localrefs IIRC。可能取决于Android版本。对于这个 sn-p 没关系,但是如果在循环中调用 NewStringUTF,删除它们是有意义的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-16
  • 2016-12-05
  • 1970-01-01
相关资源
最近更新 更多