1. Nimm jetzt an unserem Uhans - 3. ADVENT - Gewinnspiel teil - Alle Informationen findest Du hier!

Ein lauffähiges C Programm + Android NDK = Merkwürdiges Verhalten

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von Samsung I7500, 07.03.2012.

  1. Samsung I7500, 07.03.2012 #1
    Samsung I7500

    Samsung I7500 Threadstarter Fortgeschrittenes Mitglied

    Beiträge:
    359
    Erhaltene Danke:
    4
    Registriert seit:
    20.06.2009
    Moin! Ich habe ein in C geschriebenes Programm, welches auf meinen PCs ohne weiteres problemlos läuft. Nun versuche ich es mittels Android NDK auf Android lauffähig zu bekommen. Dort spinnt das ganze aber total rum. Ein Beispiel:

    Ich habe ein Array in das ich beliebig Elemente einfügen kann. Anschließend habe ich eine Methode, die mir die Anzahl der Elemente des Arrays ausgibt. Unter C ist das in dem Fall eine Integer Variable die beim Hinzufügen von Elementen incrementiert wird. Während mir das Programm auf dem PC immer die korrekte Anzahl der Elemente ausgibt beträgt diese bei der Android Ausgabe immer 1, egal wieviele neue Elemente ich einfüge. Bei leerer Liste hingegen stürzt mir das Programm einfach ab.

    Nun frage ich mich woher dieses Verhalten kommt. Das Programm selbst läuft wie gesagt sowohl auf Linux als auch auf Windows oder OsX ohne Probleme. Für Windows speziell habe ich mir noch einen C# Wrapper geschrieben um das Programm unter .NET nutzen zu können. Läuft auch super. Aber unter Android ausgeführt spackt es einfach nur rum, obwohl der Build (ndk-build unter CygWin) problemlos verläuft.

    Gibt es da etwa irgendwas spezielles zu beachten wenn man mit C Programme mit NDK auf Android portiert? Irgendwelche NDK Eigenarten oder sowas? Evtl. irgendwie anders kompilieren oder so?

    Besten Dank schonmal...
     
  2. Unicate, 07.03.2012 #2
    Unicate

    Unicate Android-Experte

    Beiträge:
    473
    Erhaltene Danke:
    57
    Registriert seit:
    09.08.2010
    Also hier mal eine Frage NativeActivity oder JNI?

    Abstürzen des Programms bei leerer Liste klingt nach falsch oder gar nicht initialisiert.

    Zeig mal den Code her, vielleicht sehen wir was was du nicht siehst.
    Ich habe bereits einigen Code im Android native erstellt (JNI sowohl als auch über NativeActivity) und hatte bisher keine Probleme.
     
  3. Samsung I7500, 07.03.2012 #3
    Samsung I7500

    Samsung I7500 Threadstarter Fortgeschrittenes Mitglied

    Beiträge:
    359
    Erhaltene Danke:
    4
    Registriert seit:
    20.06.2009
    JNI, von Native Activity hab ich bisher noch nichts gehört, hab mich soweit aber auch noch nicht mit dem NDK beschäftigt.

    3 Strukturen:
    Code:
    struct mp_model {
        struct mp_label_collection *label_collection;
    };
    
    struct mp_label_collection {
        int labels;
        struct mp_label **label_list;
    };
    
    struct mp_label {
        char *name;
    };
    
    Library
    Code:
    
    struct mp_model *default_model;
    
    void library_init() {
    
        if((default_model = malloc(sizeof(struct mp_model))) == NULL) {
            exit(1);
        }
    
        (*default_model).label_collection = alloc_label_collection();
    }
    
    Resourcen
    Code:
    struct mp_label_collection *alloc_label_collection() {
    
        struct mp_label_collection *temp = NULL;
    
        if((temp = malloc(sizeof(struct mp_label_collection))) == NULL) {
            exit(1);
        }
    
        (*temp).labels = 0;
    
        (*temp).label_list = malloc(0);
    
        return temp;
    }
    
    struct mp_label *create_label(char *name) {
    
        struct mp_label *temp = NULL;
    
        if((temp = malloc(sizeof(struct mp_label))) == NULL) {
            exit(1);
        }
    
        if(((*temp).name = malloc(strlen(name)+1)) == NULL) {
            exit(1);
        }
        (*temp).name = strcpy((*temp).name, name);
    
        return temp;
    }
    
    Fügt ein Label zur Collection hinzu
    Code:
    void add_label_to_label_collection(struct mp_label_collection *collection, struct mp_label *label) {
    
        if(((*collection).label_list = realloc((*collection).label_list, ((*collection).labels + 1) * sizeof(struct mp_label))) == NULL) {
            exit(1);
        }
    
        // Hier wird das Label zum Array hinzugefügt
        (*collection).label_list[(*collection).labels] = label;
        
        // Hier wird der Counter incrementiert, der später zurückgegeben werden soll.
        (*collection).labels++;
    }
    
    Anzahl Labels:
    Code:
    int library_count_labels() {
        return (*(*default_model).label_collection).labels;
    }
    
    Und so würde das ganze aufgerufen werden:
    Code:
    // Initializiert Library
    library_init();
    
    // Erstellt Labels und fügt diese zum Array hinzu
    add_label_to_label_collection((*default_model).label_collection, mp_create_label("Label 1"));
    add_label_to_label_collection((*default_model).label_collection, mp_create_label("Label 2"));
    add_label_to_label_collection((*default_model).label_collection, mp_create_label("Label 3"));
    
    // Liefert die Anzahl der Labels zurück, unter Android wie schon erwähnt andauernd 1
    library_count_labels();
    
    Soweit funktioniert das alles auch, murkst unter Android aber eben rum, da library_count_labels() ständig ne 1 zurückliefert, und wenn ich gar nichts zur Liste hinzufüg das Programm eben abkackt. Hier nochmal mein JNI Code
    Code:
    jstring Java_com_android_mediaplayer_AndroidMediaPlayerActivity_createLabel(JNIEnv* env, jobject javaThis, jstring label) {
    
        mp_library_init();
    
        mp_library_create_label(jstringTostring(env, label));
    
        return (*env)->NewStringUTF(env, jstringTostring(env, label));
    }
    
    jint Java_com_android_mediaplayer_AndroidMediaPlayerActivity_countLabels(JNIEnv *env, jobject javaThis) {
        return mp_library_count_labels();
    }
    
    Da hab ich gleich im übrigen noch eine Frage dazu: Inwieweit sind jString und char* zueinander kompatibel? Gerade bei der return Zeile da hab ich herausgefunden dass ich aus nem jString scheinbar nen char* machen muss damit ich es C seitig wieder in NewStringUTF packen kann, also quasi unter C mit arbeiten kann. Ist das richtig so? Und gilt das auch für andere Typen?

    Vielen dank schonmal
     

Diese Seite empfehlen