jni数据类型

最近使用的 ndk 开发一些程序,涉及到了动态注册 jni 接口的问题,在此先总结下数据类型

jni数据类型_第1张图片

如上图jni数据类型对应表,包含了大多数数据类型

其中主要用来动态的注册的接口中的是 Field 描述那栏,动态注册的方式如下:

    #ifndef NELEM
    # define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
    #endif

    #define __android_second(dummy, second, ...)     second

    /* If passed multiple args, returns ',' followed by all but 1st arg, otherwise
     * returns nothing.
     */
    #define __android_rest(first, ...)               , ## __VA_ARGS__

    #define android_printAssert(cond, tag, fmt...) \
        __android_log_assert(cond, tag, \
    	__android_second(0, ## fmt, NULL) __android_rest(fmt))

    #define CONDITION(cond)     (__builtin_expect((cond)!=0, 0))

    #ifndef LOG_ALWAYS_FATAL_IF
    #define LOG_ALWAYS_FATAL_IF(cond, ...) \
       ( (CONDITION(cond)) \
         ? ((void)android_printAssert(#cond, LOG_TAG, ## __VA_ARGS__)) \
         : (void)0 )
    #endif

    #ifndef LOG_ALWAYS_FATAL
    #define LOG_ALWAYS_FATAL(...) \
         ( ((void)android_printAssert(NULL, LOG_TAG, ## __VA_ARGS__)) )
    #endif

    #ifndef LOG_FATAL_IF
    #define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ## __VA_ARGS__)
    #endif

    #ifndef LOG_FATAL
    #define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
    #endif

    #define FIND_CLASS(var, className) \
    	var = env->FindClass(className); \
    	LOG_FATAL_IF(! var, "Unable to find class " className);

    #define GET_STATIC_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
    	var = env->GetStaticMethodID(clazz, methodName, fieldDescriptor); \
    	LOG_FATAL_IF(! var, "Unable to find static method" methodName);
    #define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
    	var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
    	LOG_FATAL_IF(! var, "Unable to find method" methodName);

    #define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
    	var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
    	LOG_FATAL_IF(! var, "Unable to find field " fieldName);

    struct fields_t {
        jclass clazz;
        jfieldID context;
        jmethodID program;
    };
    static fields_t mCObjectFields;

    static JNINativeMethod method_table[] = {
            {"native_create",      "()I",
                    (void *) create},
            {"native_destroy",     "()I",
                    (void *) destroy},
    };

    int register_com_llvision_middleout_CLEngine(JNIEnv *env) {
        FIND_CLASS(mCObjectFields.clazz, "com/XXX/CObject");
        GET_FIELD_ID(mCObjectFields.context, mCObjectFields.clazz, "mNativePtr", "I");
        GET_METHOD_ID(mCObjectFields.loadProgram, mCObjectFields.clazz, "program", "(Ljava/lang/String;)I");
        return (env)->RegisterNatives(mCObjectFields.clazz, method_table, NELEM(method_table));
    }

这样就能动态为 com.XXX.CObject 对象注册两个本地函数,分别为 native_create() 和 native_destroy() 等。

你可能感兴趣的:(jni,android,ndk,Android开发)