一、JNI基礎

5898 ワード

一、JNI開発の手順;
二、スタティックライブラリとダイナミックライブラリの違い。
三、JNIEVとは何ですか?
四、JNI基本データタイプ;
五、常用命令:javah、javap;
六、JNIはJava類のオブジェクトのフィールド、非静的方法、静的方法、構造方法を呼び出します。
七、JNIタイプのサイン
=======================================================一、JNI開発の手順1.native方法を作成します。2.javah命令、生成.hファイル(または自分で手書き);java_クラスのフルネームメソッド名3.コピー.hヘッダファイルをcppプロジェクトにコピーします。4.jni.hとjni_をコピーする。md.h5.実現.hヘッダファイルの宣言関数。6.一つ.dll/soダイナミックライブラリを生成する。(サポートされているcpuアーキテクチャタイプを設定する)7.javaにダイナミックライブラリをロードする。8.native関数を呼び出します。
二、スタティックライブラリとダイナミックライブラリの違い。関数ライブラリは、スタティックライブラリとダイナミックライブラリの2つに分類されます。1.スタティックライブラリはプログラムのコンパイル時にターゲットコードに接続されます。プログラムの実行時にはこのスタティックライブラリは不要になります。2.ダイナミックライブラリはプログラムコンパイル時にターゲットコードに接続されず、プログラム実行時にロードされますので、プログラム実行時にダイナミック在庫が必要です。
1、スタティック関数ライブラリの名前は普通libxx.aです。静的関数ライブラリを用いてコンパイルされたファイルは比較的大きいです。関数ライブラリ全体のデータはターゲットコードに統合されるので、彼の利点は明らかです。つまり、コンパイル後の実行プログラムは外部の関数ライブラリサポートが必要ではありません。すべての使用関数がコンパイルされているからです。もちろんこれも彼の欠点になります。もし静的な関数ライブラリが変更されたら、あなたのプログラムは再コンパイルしなければなりません。
2、ダイナミック関数ライブラリの名前は普通libxx.soです。静的関数ライブラリに対して、動的関数ライブラリはコンパイル時にターゲットコードにコンパイルされていません。あなたのプログラムは相関関数を実行する時にこの関数ライブラリの対応関数を呼び出します。したがって、ダイナミック関数ライブラリによって生成される実行可能ファイルは比較的小さいです。関数ライブラリはあなたのプログラムに統合されていません。プログラム実行時に動的に申請して呼び出しますので、プログラムの実行環境には対応するライブラリを提供しなければなりません。ダイナミック関数ライブラリの変更はあなたのプログラムに影響しませんので、ダイナミック関数ライブラリのアップグレードが便利です。
三、JNIEVとは何ですか?JNIEnvはスレッド関連のJNI環境を表す構造体である。JavaVMとJNIEVvの関係:1、JavaVMのAttach CurrenntThread関数を呼び出すと、このスレッドのJNIEnv構造体が得られます。このようにして、バックグラウンドスレッドでJava関数をフィードバックすることができる。2、バックグラウンドスレッドが終了する前に、JavaVMのDetachCurentThread関数を呼び出して対応リソースをリリースする必要があります。
/*
 * JNI Native Method Interface.
 */
struct JNINativeInterface_;
struct JNIEnv_;

#ifdef __cplusplus
typedef JNIEnv_ JNIEnv;
#else
typedef const struct JNINativeInterface_ *JNIEnv;
#endif

struct JNINativeInterface_ {
    void *reserved0;
    void *reserved1;
    void *reserved2;
    void *reserved3;
    jint (JNICALL *GetVersion)(JNIEnv *env);
    jclass (JNICALL *DefineClass)
      (JNIEnv *env, const char *name, jobject loader, const jbyte *buf,
       jsize len);
    jclass (JNICALL *FindClass)
      (JNIEnv *env, const char *name);
......... 

}; 

struct JNIEnv_ {
    const struct JNINativeInterface_ *functions;

#ifdef __cplusplus
    jint GetVersion() {
        return functions->GetVersion(this);
    }

    jclass DefineClass(const char *name, jobject loader, const jbyte *buf, jsize len) {
        return functions->DefineClass(this, name, loader, buf, len);
    }

    jclass FindClass(const char *name) {
            return functions->FindClass(this, name);
    }
    .........
#endif /* __cplusplus */

};

/*
 * We use inlined functions for C++ so that programmers can write:
 *    env->FindClass("java/lang/String")
 * in C++ rather than:
 *    (*env)->FindClass(env, "java/lang/String")in C.
 */

==================================
* * *
==================================

/*
 * JNI Invocation Interface.
 */

struct JNIInvokeInterface_;
struct JavaVM_;

#ifdef __cplusplus
        typedef JavaVM_ JavaVM;
#else
        typedef const struct JNIInvokeInterface_ *JavaVM;
#endif

struct JNIInvokeInterface_ {
    void *reserved0;
    void *reserved1;
    void *reserved2;

    jint (JNICALL *DestroyJavaVM)(JavaVM *vm);
    jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args);
    jint (JNICALL *DetachCurrentThread)(JavaVM *vm);
    jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version);
    jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args);
};

struct JavaVM_ {
    const struct JNIInvokeInterface_ *functions;
#ifdef __cplusplus
    jint DestroyJavaVM() {
        return functions->DestroyJavaVM(this);
    }

    jint AttachCurrentThread(void **penv, void *args) {
        return functions->AttachCurrentThread(this, penv, args);
    }

    jint DetachCurrentThread() {
        return functions->DetachCurrentThread(this);
    }

    jint GetEnv(void **penv, jint version) {
        return functions->GetEnv(this, penv, version);
    }

    jint AttachCurrentThreadAsDaemon(void **penv, void *args) {
        return functions->AttachCurrentThreadAsDaemon(this, penv, args);
    }

#endif

};
1.なぜJNIEnvに入る必要がありますか?関数実行中にJNIEnv 2.C++が必要ですが、なぜ入ってきませんでしたか?this 3.C++はCのセットだけをパッケージ化して、変数にポインタを与えます。この変数は2級のポインタC/C++の中になぜ違いがありますか?
四、JNI基本データタイプ;基本データタイプ変換
#ifdef HAVE_INTTYPES_H
# include       /* C99 */
typedef uint8_t         jboolean;       /* unsigned 8 bits */
typedef int8_t          jbyte;          /* signed 8 bits */
typedef uint16_t        jchar;          /* unsigned 16 bits */
typedef int16_t         jshort;         /* signed 16 bits */
typedef int32_t         jint;           /* signed 32 bits */
typedef int64_t         jlong;          /* signed 64 bits */
typedef float           jfloat;         /* 32-bit IEEE 754 */
typedef double          jdouble;        /* 64-bit IEEE 754 */
#else
typedef unsigned char   jboolean;       /* unsigned 8 bits */
typedef signed char     jbyte;          /* signed 8 bits */
typedef unsigned short  jchar;          /* unsigned 16 bits */
typedef short           jshort;         /* signed 16 bits */
typedef int             jint;           /* signed 32 bits */
typedef long long       jlong;          /* signed 64 bits */
typedef float           jfloat;         /* 32-bit IEEE 754 */
typedef double          jdouble;        /* 64-bit IEEE 754 */
#endif
五、常用命令:javah、javap 1.javah.2.javap-s-p:クラスフィールドと方法の署名情報を取得する。3.javap-s-p-v:クラスの中の方法のdescriptor flagsを見ることができる。
六、JNIはJava類のオブジェクトのフィールド、非静的方法、静的方法、構造方法を呼び出します。
七、JNIタイプ署名1、JNI関数署名情報は、パラメータタイプと戻り値タイプが共同で構成されています。2、なぜ署名情報が必要かというと、Javaサポート関数の再負荷、すなわち同名の異なるパラメータの関数を定義することができるからです。関数名だけでは具体的な関数が見つかりません。この問題を解決するために、JNI技術では、パラメータタイプと戻り値タイプの組み合わせを関数として署名情報として、署名情報と関数名があり、Javaの関数を正確に見つけることができます。
3、どのように関数または変数の署名情報を生成しますか?javap-s-p xxx