JNIEXPORT jint JNI_OnLoad(
    JavaVM* vm,
    void* reserved
)
1.0、参考
1.1、此函数的作用

public static void System.loadLibrary(String libName)public static void System.load(String fileName)加载动态库时的回掉函数

1.2、参数说明

JavaVM的定义如下:

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

    jint (*DestroyJavaVM)(JavaVM*);
    jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);
    jint (*DetachCurrentThread)(JavaVM*);
    jint (*GetEnv)(JavaVM*, void**, jint);
    jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);
};

struct _JavaVM {
    const struct JNIInvokeInterface* functions;

    #if defined(__cplusplus)
        jint DestroyJavaVM() { 
            return functions->DestroyJavaVM(this);
        }
        jint AttachCurrentThread(JNIEnv** p_env, void* thr_args) {
            return functions->AttachCurrentThread(this, p_env, thr_args);
        }
        jint DetachCurrentThread() {
            return functions->DetachCurrentThread(this);
        }
        jint GetEnv(void** env, jint version) {
            return functions->GetEnv(this, env, version);
        }
        jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args) {
            return functions->AttachCurrentThreadAsDaemon(this, p_env, thr_args);
        }
    #endif
};

#if defined(__cplusplus)
    typedef _JavaVM JavaVM;
#else
    typedef const struct JNIInvokeInterface* JavaVM;
#endif

JavaVM的定义在CC++中不相同。原因是C中的结构体不允许包含函数,而C++中的结构体是允许包含函数的。C++中有this关键字,而C中是没有该关键字的。因为,为了让C++的代码更容易编写,就定义了不同的结构。

void *reserved是预留的参数,暂无实际用处。

1.3、返回值说明

jint的定义如下:

typedef int32_t  jint; /* signed 32 bits */

jintJava中的int类型占用相同的内存空间

该函数的返回值为JNI版本号。可以使用下面的

#define JNI_VERSION_1_1 0x00010001
#define JNI_VERSION_1_2 0x00010002
#define JNI_VERSION_1_4 0x00010004
#define JNI_VERSION_1_6 0x00010006

该函数的返回值是告诉JVM使用哪一个版本的JNI。 如果你的动态库没有编写或者没有导出此函数,默认使用JNI_VERSION_1_1

JNIEXPORT的定义如下:

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

__attribute__是由编译器定义的GCCClang都支持

visibility ("default")就相当于其他语言中的public,表示该函数可以被外部调用,如果没有此修饰, 默认是只能在该动态库内部使用。

1.4、使用示例

使用cc命令编译:

cc -lpthread -o test_pthread test.c

注意

main函数的return语句是退出进程,一旦执行到main函数的return语句,表示进程退出, 但是如果在return语句之前调用了pthread_exit()函数的话,如果还有其他进程在执行的话,就不会退出进程。