quando utilizzare JNIEXPORT e JNICALL in Android NDK?

Sto cercando di scrivere le mie fonti di jni. Guardando alcuni campioni di ndk, ho scoperto che spesso utilizzano quelle macro JNIEXPORT e JNICALL follewed con il nome del pacchetto java come questo

JNIEXPORT void JNICALL Java_com_example_plasma_PlasmaView_renderPlasma(JNIEnv * env, jobject obj, jobject bitmap, jlong time_ms)

  • Versione errata di keystore su chiamata android
  • Google Maps v2 su dispositivi android con minSDK sotto 11
  • La base di dati di Android ricrea each volta che viene avviata l'applicazione
  • StatusCallback non chiamato dopo requestNewReadPermissions quindi requestNewPublishPermissions
  • Come get l'indirizzo IP di Emulator Android?
  • Valore Alpha predefinito della barra di navigazione in Lollipop
  • L'ho scoperto ma non riesco a capire quando e come utilizzare queste macro

  • Orientamento e valori dello schermo in manifest.xml
  • Come posso implementare il certificato di certificazione SSL durante l'utilizzo di React Native
  • numero di build manifesto android
  • Come aggiornare il database dei media Android
  • Mostra popup quando l'accesso alla posizione è disabilitato dall'utente (Andorid Google Maps)
  • API di PhoneGap per interrogare i registri chiamate
  • 4 Solutions collect form web for “quando utilizzare JNIEXPORT e JNICALL in Android NDK?”

    JNIEXPORT e JNICALL sono definiti in NDK_ROOT / platforms / android-9 / arch-arm / usr / include / jni.h. A seconda del tuo setup questo path sarà diverso, ma per lo più simile.

     #define JNIIMPORT #define JNIEXPORT __attribute__ ((visibility ("default"))) #define JNICALL 

    JNIEXPORT viene utilizzato per fare apparire le funzioni native nella tabella dynamic del file binario (* .so). Possono essere impostati su "nascosti" o "predefiniti" (maggiori informazioni qui ). Se queste funzioni non si trovano nella tabella dynamic, JNI non sarà in grado di trovare le funzioni per chiamarle in modo che la chiamata di RegisterNatives non riesca a runtime.

    Vale la pena notare che tutte le funzioni finiscono nella tabella dynamic per impostazione predefinita, quindi chiunque potrebbe decompilare facilmente il tuo codice nativo. Ogni chiamata di function è incorporata nel binario nel caso in cui il JNI ha bisogno di trovarlo. Questo può essere modificato utilizzando l'opzione di compilazione -fvisibility . Consiglierei tutti di impostare questo a -fvisibility=hidden per mantenere il codice protetto e quindi utilizzare JNIEXPORT per contrassegnare le funzioni come avere visibilità esterna.

    Utilizzando il command strip solo rimuove i simboli di debug, la tabella dynamic è separata. Avere un gioco con objdump per vedere quanto una persona potrebbe uscire dai tuoi file .so.

    Recentemente siamo stati accolti da questo, spero che questo aiuti qualcuno.

    EDIT: utilizziamo un sistema di build personalizzato, quindi l'opzione di visibilità può essere impostata per impostazione predefinita per altre configurazioni di build. Ulteriori informazioni sono disponibili in questa risposta .

    È ansible trovare la definizione di tali macro nella parte dipendente dalla macchina del tuo JNI (di solito in $JAVA_HOME/include/<arch>/jni-md.h ).

    In breve, JNIEXPORT contiene tutte le direttive di compilazione necessarie per assicurare che la determinata function venga esportta correttamente. Su android (e altri sisthemes basati su Linux), che sarà vuoto.

    JNICALL contiene tutte le direttive di compilazione necessarie per garantire che la function viene trattata con la convenzione di chiamata appropriata. Probabilmente vuoto anche su android (è __stdcall su w32).

    In genere, dovresti lasciarli, anche se sono vuoti #define .

    Basta eseguire 'javah' sulle tue classi natali e utilizzare tutto ciò che genera. Non c'è bisogno di conoscere i vantaggi di questo strumento quando si dispone di uno strumento che può produrlo con un'affidabilità del 100%.

    In parole povere:

    • JNIEXPORT se si dovrebbe utilizzare la famiglia di funzioni di registerNatives allora non si dovrebbe utilizzare JNIEXPORT. Altrimenti dovresti usarlo.
    • JNICALL deve essere utilizzato SEMPRE.

    JNIEXPORT assicura che la function sia visibile nella tabella dei simboli. JNICALL assicura che la function utilizzi la convenzione di chiamata corretta. Su Android JNICALL ha un valore diverso basato sull'architettura. L'ARM è vuoto che potrebbe inganno a non includerlo. Ma devi usare JNICALL.

    registerNatives consente di colbind la function in modo programmato su JNI_onLoad o anche in futuro. registerNatives consente di recuperare nomi di funzioni errati in precedenza e raccommand questa rotta.

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.