使用Java和Kotlin作为基本语言时Native C ++ Android项目的不同行为

Iro*_*awk 5 c++ java android android-ndk kotlin

我创建了两个Native C ++项目-一个使用Kotlin作为基本语言,另一个使用Java。

在这两个项目中,我对自动创建的C ++函数进行了相同的修改:

extern "C" JNIEXPORT jstring JNICALL
Java_com_stellarsolvers_test_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */,
        jstring s) {

    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}
Run Code Online (Sandbox Code Playgroud)

因此,我添加了参数:jstring s

还可以通过以下方式修改定义:

科特林:

external fun stringFromJNI(s: String): String
Run Code Online (Sandbox Code Playgroud)

Java:

public native String stringFromJNI(String s);
Run Code Online (Sandbox Code Playgroud)

在调用代码中,我为此函数提供了一个字符串值:

科特林:

sample_text.text = stringFromJNI("Kotlin")
Run Code Online (Sandbox Code Playgroud)

Java:

tv.setText(stringFromJNI("Java"));
Run Code Online (Sandbox Code Playgroud)

两个项目都没有其他更改。

这两个项目均来自“ Native C ++”模板

  • Android Studio 3.3
  • Build#AI-182.5107.16.33.5199772,建于2018年12月25日
  • JRE:1.8.0_152-release-1248-b01 x86_64
  • JVM:JetBrains sro的OpenJDK 64位服务器VM
  • macOS 10.14.2

“创建新项目”向导中的单个更改是:

  • 最低API级别:API 21

我希望两个项目都能正常工作。

使用Java就是这种情况。

但是,Kotlin应用程序的行为方式却很奇怪:当执行到达应调用C ++函数的位置时,程序将在调试器中使用SIGSEGV崩溃:

  • 虚拟设备:Nexus 5X API 28 x86(Android 9,API 28)

调试堆栈跟踪为:

art_sigsegv_fault 0x00000000e7e571d0
art::FaultManager::HandleFault(int, siginfo*, void*) 0x00000000e7e57774
art::art_fault_handler(int, siginfo*, void*) (.llvm.650222801) 0x00000000e7e5749b
___lldb_unnamed_symbol22$$app_process32 0x00000000598aa6af
___lldb_unnamed_symbol2$$libc.so 0x00000000eace1c50
art::ManagedStack::ShadowFramesContain(art::StackReference<art::mirror::Object>*) const 0x00000000e8093086
art::Thread::DecodeJObject(_jobject*) const 0x00000000e81d8ac8
<unknown> 0x00000000e876d05d
dlsym 0x00000000598a9530
Run Code Online (Sandbox Code Playgroud)

应用程序在输入本机方法时崩溃。

Kotlin应用程序如此奇怪的行为是什么原因造成的?

我只是尝试在实际设备上进行调试:ASUS Zenfone Max Pro M1(Android 8.1.0,API 27)。而且Kotlin和Java项目都可以正常工作。调试器允许输入本机方法,不会出现任何崩溃。

因此,更新后的问题状态为: 在100%的情况下,虚拟设备上的应用程序崩溃。