#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;
}
JNI用法参考
最新推荐文章于 2023-09-01 17:41:58 发布