JNI用法参考

#include <jni.h>
#include <stdio.h>
#include <android/log.h>
#include "com_example_jnitypea_MainActivity.h"

/*
 * int 数组
 */
JNIEXPORT jint JNICALL Java_com_example_jnitypea_MainActivity_sumArray(JNIEnv *env, jobject obj, jintArray arr)
{
	jint buf[10];
	jint i, sum = 0;
	env->GetIntArrayRegion(arr, 0, 10, buf);
	for (i = 0; i < 10; ++i)
	{
		sum += buf[i];
	}
	
	return sum;
}

/*
 * 二维数组
 */
JNIEXPORT jobjectArray JNICALL Java_com_example_jnitypea_MainActivity_initInt2DArray(JNIEnv *env, jclass cls, jint size)
{
	jobjectArray result;
	int i;
	jclass intArrCls = env->FindClass("[I");
	if (intArrCls == NULL)
	{
		return NULL;
	}
	result = env->NewObjectArray(size, intArrCls, NULL);
	
	if(result == NULL)
	{
		return NULL;
	}
	for(i = 0; i < size; i++)
	{
		jint tmp[256];
		int j;
		jintArray iarr = env->NewIntArray(size);
		if(iarr == NULL)
		{
			return NULL;
		}
		for(j = 0; j < size; j++)
		{
			tmp[j] = i + j;
		}
		env->SetIntArrayRegion(iarr, 0, size, tmp);
		env->SetObjectArrayElement(result, i, iarr);
		env->DeleteLocalRef(iarr);
	}
	return result;
}

/*
 * 访问成员变量
 */
JNIEXPORT void JNICALL Java_com_example_jnitypea_MainActivity_accessField(JNIEnv *env, jobject obj)
{
	jfieldID fid;
	jstring jstr;
	const char* str;
	
	/* 获取类引用 */
	jclass cls = env->GetObjectClass(obj);
	
	/* 获取类的 field ID */
	fid = env->GetFieldID(cls, "s", "Ljava/lang/String;");
	if (fid == NULL)
	{
		return;
	}
	
	/* 读取实例的 field s */
	jstr = env->GetObjectField(obj, fid);
	str = env->GetStringUTFChars(jstr, NULL);
	if (str == NULL)
	{
		return ;
	}
	env->ReleaseStringUTFChars(jstr, str);
	
	/* Create a new string and overwrite the instance field */
	jstr = env->NewStringUTF("123");
	if (jstr == NULL)
	{
		return;
	}
	env->SetObjectField(obj, fid, jstr);
}


/*
 * 访问静态成员变量
 */
JNIEXPORT void JNICALL Java_com_example_jnitypea_MainActivity_accessStaticField(JNIEnv *env , jobject obj)
{
	jfieldID fid;
	jint si;
	
	/* Get a reference to obj's class */
	jclass cls = env->GetObjectClass(obj);
	
	/* Look for the static field si in cls */
	fid = env->GetStaticFieldID(cls, "si", "I");
	if (fid == NULL)
	{
		return;
	}
	
	/* Access the static field si */
	si = env->GetStaticIntField(cls, fid);
	
	/* Set the static field si */
	env->SetStaticIntField(cls, fid, 200);
}


/*
 * 回调成员函数
 */
JNIEXPORT void JNICALL Java_com_example_jnitypea_MainActivity_nativeMethod(JNIEnv *env, jobject obj)
{
	jclass cls = env->GetObjectClass(obj);
	jmethodID mid = env->GetMethodID(cls, "callback", "()V");
	
	if (mid == NULL)
	{
		return;
	}
	env->CallVoidMethod(obj, mid);
}


/*
 * 回调静态成员函数
 */
JNIEXPORT void JNICALL Java_com_example_jnitypea_MainActivity_nativeStaticMethod(JNIEnv *, jobject)
{
	jclass cls = env->GetObjectClass(obj);
	jmethodID mid = env->GetStaticFieldID(cls, "callback", "()V");
	if (mid == NULL)
	{
		return;
	}
	
	/* 必须通过类引用去调用 */
	env->CallStaticVoidMethod(cls, mid);
}


/*
 * 实现一个 NewString 函数,从 Unicode 字符串转换成 jstring
 */
jstring MyNewString(JNIEnv *env, jchar *chars, jint len)
{
	jclass stringClass;
	jmethodID cid;
	jcharArray elemArr;
	jstring result;
	
	stringClass = env->FindClass("java/lang/String");
	if (stringClass == NULL)
	{
		return NULL;
	}
	
	/* Get the method ID for the String(char[]) constructor */
	cid = env->GetMethodID(stringClass, "<init>", "([C)V");
	if (cid == NULL)
	{
		return NULL;
	}
	
	/* Creaate a char[] that holds the string characters */
	elemArr = env->NewCharArray(len);
	if (elemArr == NULL)
	{
		return NULL;
	}
	env->SetCharArrayRegion(elemArr, 0, len, chars);

	/*
	 * 方法一,调用NewObject,把构造函数当成参数传递进去
	 */
	/* Construct a java.lang.String object */
	result = env->NewObject(stringClass, cid, elemArr);
	
	/*
	 * 方法二,先给对象分配内存,(再手动调用构造函数,也可以不调用)
	 */
	 result = env->AllocObject(stringClass);
	 if (result)
	 {
		env->CallNonvirtualVoidMethod(result, stringClass, cid, elemArr);
		/* need to check for possible exceptions */
		if (env->ExceptionCheck())
		{
			env->DeleteLocalRef(result);
			result = NULL;
		}
	 }
	
	/* Free local reference */
	env->DeleteLocalRef(elemArr);
	env->DeleteLocalRef(stringClass);
	return result;
}


/*
 * 缓存成员变量的 fieldID
 */
JNIEXPORT void JNICALL Java_InstanceFieldAccess_accessField(JNIEnv *env, jobject obj)
{
	/* cached field ID for s */
	static  jfieldID fid_s = NULL;
	
	jclass cls = env->GetObjectClass(obj);
	jstring jstr;
	const char* str;
	
	if (fid_s == NULL)
	{
		fid_s = env->GetFieldID(cls, "s", "Ljava/lang/String;");
		if (fid_s == NULL)
		{
			return;
		}
	}
	
	jstr = env->GetObjectField(obj, fid_s);
	str = env->GetStringUTFChars(jstr, NULL);
	if (str == NULL)
	{
		return;
	}
	env->ReleaseStringUTFChars(jstr, str);
	
	jstr = env->NewStringUTF("123");
	if (jstr == NULL)
	{
		return;
	}
	env->SetObjectField(obj, fid_s, jstr);
}


/*
 * 缓存成员函数的 methodID
 */
jstring MyNewString(JNIEnv *env, jchar *chars, jint len)
{
	jclass stringClass;
	jcharArray elemArr;
	static jmethodID cid = NULL;
	jstring result;
	
	stringClass = env->FindClass("java/lang/String");
	if (stringClass == NULL)
	{
		return NULL;
	}
	
	/* cid is a static variable */
	if (cid == NULL)
	{
		/* Get the method ID for the String constructor */
		cid = env->GetMethodID(stringClass, "<init>", "([C)V");
		if (cid == NULL)
		{
			return NULL;
		}
	}
	
	/* Create a char[] that holds the string characters */
	elemArr = env->NewCharArray(len);
	if (elemArr == NULL)
	{
		return NULL;
	}
	env->SetCharArrayRegion(elemArr, 0, len, chars);
	
	/* Construct a java.lang.String object */
	result = env->NewObject(stringClass, cid, elemArr);
	
	/* Free local references */
	env->DeleteLocalRef(elemArr);
	env->DeleteLocalRef(stringClass);
	return result;
}


/*
 * 初始化时缓存 field ID 和 method ID
 */
jmethodID MID_InstanceMethodCall_callback;

JNIEXPORT void JNICALL Java_com_example_jnitypea_MainActivity_initIDs(JNIEnv *env, jclass cls)
{
	MID_InstanceMethodCall_callback = env->getMethodID(cls, "callbacl", "()V");	
}


/*
 * 全局引用和局部引用 
 */
jstring MyNewString(JNIEnv *env, jchar *chars, jint len)
{
	static jclass stringClass = NULL;
	
	if (stringClass == NULL)
	{
		/* create a local reference */
		jclass localRefCls = env->FindClass("java/lang/String");
		if (localRefCls == NULL)
		{
			return NULL;
		}
		
		/* create a global reference */
		stringClass = env->NewGlobalRef(localRefCls);
		
		/* explicit free local reference */
		env->DeleteLocalRef(localRefCls);
		
		if (stringClass == NULL)
		{
			return NULL;
		}
		
		/*
		 * free global reference
		 * env->DeleteGlobalRef(stringClass);
		 */
		return stringClass;
	}
}


/*
 * 异常处理
 */
JNIEXPORT void JNICALL Java_com_example_jnitypea_MainActivity_doit(JNIEnv *env, jobject obj)
{
	jthrowable exc;
	jclass cls = env->GetObjectClass(obj);
	jmethodID mid = env->GetMethodID(cls, "throw_exception", "()V");
	
	if (mid == NULL)
	{
		return ;
	}
	env->CallVoidMethod(obj, mid);
	
	exc = env->ExceptionOccurred();
	if (exc)
	{
		// print debug message
		env->ExceptionDescribe();
		
		// clear exceptions
		env->ExceptionClear();
		
		// throw a new exception
		jclass newExcCls;
		newExcCls = env->FindClass("java/lang/IllegalArgumentException");
		if (newExcCls == NULL)
		{
			return;
		}
		env->ThrowNew(newExcCls, "thrown from native");
	}
}


/*
 * 动态注册 JNI
 */

// 方法对应表
static JNINativeMethod gMethods[] = 
{
	{"dynamicRegisterFunction", "()V", (void*)native_dynamicRegister}
};

/*
 * System.loadLibrary("lib") 时调用
 * 如果成功返回 JNI 版本,失败返回 -1
 */
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
	JNIEnv* env = NULL;
	jint result = -1;
	
	if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK)
	{
		return -1;
	}
	
	// 注册
	if (!registerNatives(env))
	{
		return -1;
	}
	
	result = JNI_VERSION_1_4;
	return result;
}

/*
 * 为类注册本地方法
 */
static int registerNative(JNIEnv *env)
{
	// 指定要注册的类
	const char* kClassName = "com/example/jnitypea/MainActivity";
	return registerNativeMethods(env, kClassName, gMethods, sizeof(gMethods)/sizeof(gMethods[0]));
}

/*
 * 为某个类注册本地方法
 */
static int registerNativeMethods(JNIEnv* env, const char* className, JNINativeMethod* gMethods, int numMethods)
{
	jclass cls;
	cls = env->FindClass(className);
	if (cls == NULL)
	{
		return JNI_FALSE;
	}
	
	if (env->RegisterNatives(cls, gMethods, numMethods) < 0)
	{
		return JNI_FALSE;
	}
	
	return JNI_TRUE;
}
















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值