Almo
Almo

Reputation: 15861

How do I figure out what's wrong with this JNI call?

I'm building a C++ library with Visual Studio and using it in an Android Studio project that I run in an emulator. If I don't use the problem code below, the rest of the project works fine.

In my java class:

public native int androidmain();

public void aFunction() {
    androidmain();
}

And in my C++ library:

#if defined( PLATFORM_ANDROID )
extern "C" {
    JNIEXPORT jint JNICALL Java_com_TestsRunnerAndroid2015_TestsRunnerAndroid2015_androidmain( JNIEnv * env, jobject, jobjectArray argsObj ) {

        OutputString( "androidmain called" ); // ALMODEBUG

        jsize stringCount = 0;
        if ( env == nullptr ) {
            OutputString( "env is null" );
        } else {
            OutputString( "env is not null" );
        }
        if ( argsObj != nullptr ) {
            OutputString( "argsObj was not null" );
            stringCount = env->GetArrayLength( argsObj ); // CRASH HERE
            OutputString( "Got argsObj length." );
        } else {
            OutputString( "argsObj was null" );
        }
...

The output I get from this is:

D/TAG: androidmain called
D/TAG: env is not null
D/TAG: argsObj was not null
W/art: Suspending all threads took: 94.170ms
A/art: art/runtime/java_vm_ext.cc:470] JNI DETECTED ERROR IN APPLICATION: use of invalid jobject 0x12c62000
A/art: art/runtime/java_vm_ext.cc:470]     from int com.TestsRunnerAndroid2015.TestsRunnerAndroid2015.androidmain()

Additional comment: I'm aware I'm sending no arguments, yet parsing an argument array. I'm expecting the count of objects to be zero.

Upvotes: 1

Views: 284

Answers (1)

SolutionMill
SolutionMill

Reputation: 667

In Java code you declare androidmain() as not taking any arguments, but in C code you declare Java_com_TestsRunnerAndroid2015_TestsRunnerAndroid2015_andro‌​idmain(...) as taking an array of objects as an argument.

In Java code, when calling androidmain() you are not supplying argsObj argument for Java_com_TestsRunnerAndroid2015_TestsRunnerAndroid2015_andro‌​idmain(...)

Try declaring androidmain as public native int androidmain(Object[] argsObj); and when you call it -- pass that argument.

Upvotes: 2

Related Questions