From ec4dfdfc5826767974b6840edcb0fe1c26b29bb8 Mon Sep 17 00:00:00 2001 From: Philipp Wiesemann Date: Fri, 17 Oct 2014 23:36:45 +0200 Subject: [PATCH] Fixed bug 2476 - Allow custom main() arguments rettichschnidi I would like to pass custom arguments from my Java code (subclass of SDLActivity) to the native SDL2 binary. --- .../src/org/libsdl/app/SDLActivity.java | 14 +++++- src/main/android/SDL_android_main.c | 46 ++++++++++++++++--- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/android-project/src/org/libsdl/app/SDLActivity.java b/android-project/src/org/libsdl/app/SDLActivity.java index c3e0a8782..8b6c8e9c9 100644 --- a/android-project/src/org/libsdl/app/SDLActivity.java +++ b/android-project/src/org/libsdl/app/SDLActivity.java @@ -61,6 +61,16 @@ public class SDLActivity extends Activity { System.loadLibrary("main"); } + /** + * This method is called by SDL using JNI. + * This method is called by SDL before starting the native application thread. + * It can be overridden to provide the arguments after the application name. + * The default implementation returns an empty array. It never returns null. + * @return arguments for the native application. + */ + protected String[] getArguments() { + return new String[0]; + } public static void initialize() { // The static nature of the singleton and Android quirkyness force us to initialize everything here @@ -277,7 +287,7 @@ public class SDLActivity extends Activity { } // C functions we call - public static native int nativeInit(); + public static native int nativeInit(Object arguments); public static native void nativeLowMemory(); public static native void nativeQuit(); public static native void nativePause(); @@ -802,7 +812,7 @@ class SDLMain implements Runnable { @Override public void run() { // Runs SDL_main() - SDLActivity.nativeInit(); + SDLActivity.nativeInit(SDLActivity.mSingleton.getArguments()); //Log.v("SDL", "SDL thread terminated"); } diff --git a/src/main/android/SDL_android_main.c b/src/main/android/SDL_android_main.c index ff55a95f7..08102f8ea 100644 --- a/src/main/android/SDL_android_main.c +++ b/src/main/android/SDL_android_main.c @@ -17,22 +17,54 @@ extern void SDL_Android_Init(JNIEnv* env, jclass cls); /* Start up the SDL app */ -int Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj) +int Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject array) { + int i; + int argc; + int status; + /* This interface could expand with ABI negotiation, callbacks, etc. */ SDL_Android_Init(env, cls); SDL_SetMainReady(); - /* Run the application code! */ + /* Prepare the arguments. */ + + int len = (*env)->GetArrayLength(env, array); + char* argv[1 + len + 1]; + argc = 0; /* Use the name "app_process" so PHYSFS_platformCalcBaseDir() works. https://bitbucket.org/MartinFelis/love-android-sdl2/issue/23/release-build-crash-on-start */ - int status; - char *argv[2]; - argv[0] = SDL_strdup("app_process"); - argv[1] = NULL; - status = SDL_main(1, argv); + argv[argc++] = SDL_strdup("app_process"); + for (i = 0; i < len; ++i) { + const char* utf; + char* arg = NULL; + jstring string = (*env)->GetObjectArrayElement(env, array, i); + if (string) { + utf = (*env)->GetStringUTFChars(env, string, 0); + if (utf) { + arg = SDL_strdup(utf); + (*env)->ReleaseStringUTFChars(env, string, utf); + } + } + if (!arg) { + arg = SDL_strdup(""); + } + argv[argc++] = arg; + } + argv[argc] = NULL; + + + /* Run the application. */ + + status = SDL_main(argc, argv); + + /* Release the arguments. */ + + for (i = 0; i < argc; ++i) { + SDL_free(argv[i]); + } /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */ /* exit(status); */