java jni 头文件生成

jni头文件生成

eclipse下

eclpse下,在java类代码中加载jni动态库,定义好native函数后,在项目代码目录的bin\classes下,cmd输入命令:javah -jni 类名如 >javah -jni com.skyworth.autotest.common.Aut
oTestParamTrans后就会在bin\classes生成头文件,然后实现该头文件中的函数即可;

package com.penghui.testjni;
public class Autotest{
        public native boolean isConnected();  
        static
        {
                System.loadLibrary("hello");
        }
}

执行:javah -jni com.penghui.testjni.Autotest

其他方式

命令行下,如linux下或者直接用Windows的cmd
假如手动编辑上述java代码:
1. 先新建com/penghui/testjni/目录
2. cd到新建的目录中编辑上述代码Autotest.java
3. 然后cd到原目录,执行javac com/penghui/testjni/Autotest.java在com/penghui/testjni/下生成Autotest.class
4. 执行javah -jni com.penghui.testjni.Autotest 在 本目录生成com_penghui_testjni_Autotest.h(注意,如果之前存在com_penghui_testjni_Autotest.h,需要先删掉,在执行命令生成)
com_penghui_testjni_Autotest.h内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class com_penghui_testjni_Autotest */

#ifndef _Included_com_penghui_testjni_Autotest
#define _Included_com_penghui_testjni_Autotest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_penghui_testjni_Autotest
 * Method:    isConnected
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_com_penghui_testjni_Autotest_isConnected
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

JNI_OnLoad与JNI_OnUnload

在Android中,当程序在java层运行System.loadLibrary(“jnitest”);这行代码后,程序会去载入libjnitest.so文件,与此同时,产生一个”Load”事件,这个事件触发后,程序默认会在载入的.so文件的函数列表中查找JNI_OnLoad函数并执行,与”Load”事件相对,当载入的.so文件被卸载时,“Unload”事件被触发,此时,程序默认会去在载入的.so文件的函数列表中查找JNI_OnUnload函数并执行,然后卸载.so文件。需要注意的是,JNI_OnLoad与JNI_OnUnload这两个函数在.so组件中并不是强制要求的,用户也可以不去实现,java代码一样可以调用到C组件中的函数,在接下来的章节中会讲到这点。
之所以在C组件中去实现这两个函数(特别是JNI_OnLoad函数),往往是做一个初始化工作或“善后”工作。可以这样认为,将JNI_ONLoad看成是.so组件的初始化函数,当其第一次被装载时被执行(window下的dll文件也可类似的机制,在_DLL_Main()函数中,通过一个swith case语句来识别当前是载入还是卸载)。将JNI_OnUnload函数看成是析构函数,当其被卸载时被调用。
由此看来,就不难明白为什么很多jni C组件中会实现JNI_OnLoad这个函数了。 一般情况下,在C组件中的JNI_OnLoad函数用来实现给VM注册接口,以方便VM可以快速的找到Java代码需要调用的C函数。(此外,JNI_OnLoad函数还有另外一个功能,那就是告诉VM此C组件使用那一个JNI版本,如果未实现JNI_OnLoad函数,则默认是JNI 1.1版本)。

使用显式注册native jni方法


static JNINativeMethod gMethods[] = {
    {"isConnected","()I",(void *)isconnect}
};

static int register_com_penghui_testjni(JNIEnv *env)
{
    return AndroidRuntime::registerNativeMethods(env,
                "com/penghui/testjni/Autotest", gMethods, NELEM(gMethods));
}

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
        JNIEnv* env = NULL;
        jint result = -1;


        if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
                //LOGE("ERROR: GetEnv failed\n");
                goto FAIL;
        }
        assert(env != NULL);

        if (register_com_penghui_testjni(env) < 0) {

                goto FAIL;
        }
        // media_jniTest
        /* success -- return valid version number */
        result = JNI_VERSION_1_4;

        //LOGV("Leave %s %d", __FUNCTION__, __LINE__); 
FAIL:
        return result;
}

你可能感兴趣的:(android)