最近使用的 ndk 开发一些程序,涉及到了动态注册 jni 接口的问题,在此先总结下数据类型
如上图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));
}