فهرست منبع

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.
Philipp Wiesemann 11 سال پیش
والد
کامیت
ec4dfdfc58
2فایلهای تغییر یافته به همراه51 افزوده شده و 9 حذف شده
  1. 12 2
      android-project/src/org/libsdl/app/SDLActivity.java
  2. 39 7
      src/main/android/SDL_android_main.c

+ 12 - 2
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");
     }

+ 39 - 7
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); */