SDL2 and Android Java native methods

I have an Android SDL2 app that will quite happily call Java methods as follows:

void GetApplicationDirectory( char *pszDir )
{
  JNIEnv* env = (JNIEnv *) SDL_AndroidGetJNIEnv();

  // retrieve the Java instance of the SDLActivity
  jobject activity = (jobject) SDL_AndroidGetActivity();
  ...

I’m unsure how to implement native methods the other way around.

In the past I have created static libraries with my C native methods and used the following to call the methods from Java:

System.loadLibrary("nativefuncs-jni");
...
public native void MyCFunc();
...
MyCFunc();

Is it really necessary to create an additional static library when there is already libmain.so in an SDL Android project?

Can I simply use:

System.loadLibrary("libmain");   // Or "main" ?

…or is this a bad idea? Perhaps there’s a better way that’s already been provided in the SDL Android framework that I’ve missed?

The C functions that I want to add to my app will push SDL User Events to notify my C++ code that some objects have been received on the Java side.

1 Like

Yes, native methods can be implemented directly in your libmain.so.
see src/core/SDL_android.c for examples of implementations.
you also need some prototype in you java file (ex: “public static native void nativeLowMemory();” )

Sorry, I’m in need of a bit of a nudge. Attempting to call my native method is crashing the app:

01-08 21:55:48.200 31995-31995/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   java.lang.UnsatisfiedLinkError: Native method not found: org.libsdl.app.MainActivity.NativeTest:()V
                                                       at org.libsdl.app.MainActivity.NativeTest(Native Method)
                                                       at org.libsdl.app.MainActivity.onCreate(MainActivity.java:407)
                                                       at android.app.Activity.performCreate(Activity.java:5276)

In one of my .cpp files (belongs to my ‘main’ module’s Android.mk):

  #include "jni.h"

  JNIEXPORT void JNICALL Java_org_libsdl_app_MainActivity_NativeTest( JNIEnv *env, jobject obj )
  {
    LogDebugf( "NativeTest CALLED!" );
  }

In MainActivity.java:

public static native void NativeTest();
...
@Override
  protected void onCreate( Bundle savedInstanceState )
  {
    super.onCreate( savedInstanceState );

    //System.loadLibrary("libmain");  // Doesn't work
    System.loadLibrary("main");
    NativeTest();
  }

It’s late - any idea what I’m missng?

you need to add before ?

extern “C” {
JNIEXPORT void JNICALL Java_org_libsdl_app_MainActivity_NativeTest( JNIEnv *env, jobject obj );
}

Thank you! Yes -that’s the problem - C vs C++ linkage. I wonder what needs to be changed to call C++ methods instead from Java. I got 2 JNI books and they both show identical function definitions for C and C++.