jni使用小结浅析

1.下载ndk,配置下环境变量:在系统环境变量中新建变量NDKROOT ,设置ndk的安装目录E:\android\android-ndk-r10d,然后在path变量下添加如下值;%NDKROOT%;,配置此环境变量只是为了在任意目录下使用ndk-build命令
新建一个java类
package com.wonder;

public class Utils {
public static native String getString(String str);

public static native int sum(int a, int b);

public static native char getChar(char ch);

public static native byte[] getbyte(byte[] bt);

public static native int[] getIntArray(int[] arr);

//object to c
public static native void sendObj(Info info);
//c struct to java object
public static native int getInfo(Info info);

}
2.使用javah com.wonder.Utils 生成.h头文件(如果是eclipse环境,可以直接在src目录下执行该命令生成.h文件)com_wonder_Utils.h
3.编写对应的com_wonder_Utils.c文件

include

include

include “com_wonder_Utils.h”

ifdef __cplusplus

extern “C”
{

endif

typedef struct Info {
int id;
char name[100];
} Info_t;
JNIEXPORT jstring JNICALL Java_com_wonder_Utils_getString(JNIEnv *env,
jclass arg, jstring prompt) {
const char* str = (*env)->GetStringUTFChars(env, prompt, 0);

jstring res = (*env)->NewStringUTF(env, str);
(*env)->ReleaseStringUTFChars(env, prompt, str);
return res;

}

JNIEXPORT jint JNICALL Java_com_wonder_Utils_sum(JNIEnv *env, jclass arg,
jint a, jint b) {

return sum(a, b);

}

JNIEXPORT jchar JNICALL Java_com_wonder_Utils_getChar(JNIEnv *env, jclass arg,
jchar ch) {
return ch;
}

JNIEXPORT jbyteArray JNICALL Java_com_wonder_Utils_getbyte(JNIEnv *env,
jclass arg, jbyteArray byteArr) {
int len = (*env)->GetArrayLength(env, byteArr);
jbyte* jarr = (*env)->GetByteArrayElements(env, byteArr, JNI_FALSE);
jbyteArray jarrRV = (*env)->NewByteArray(env, len);
(*env)->SetByteArrayRegion(env, jarrRV, 0, len, jarr);
return jarrRV;
}

JNIEXPORT jintArray JNICALL Java_com_wonder_Utils_getIntArray(JNIEnv *env,
jclass arg, jintArray intArr) {
jsize len = (*env)->GetArrayLength(env, intArr);
jint* carr = (*env)->GetIntArrayElements(env, intArr, JNI_FALSE);
int i;
for (i = 0; i < len; i++) {
*(carr + i) += 10;
}
return intArr;

}
JNIEXPORT void JNICALL Java_com_wonder_Utils_sendObj(JNIEnv *env, jclass arg, jobject obj){
jclass cls_objClass = (*env)->GetObjectClass(env,obj);
jmethodID methodId = (*env)->GetMethodID(env,cls_objClass, “getName”,”()Ljava/lang/String;”);
jstring js_name = (jstring)(*env)->CallObjectMethod(env,obj,methodId,NULL);
}
JNIEXPORT jint JNICALL Java_com_wonder_Utils_getInfo(JNIEnv *env, jclass arg,
jobject jobj) {

//发现java Customer类,如果失败,程序返回
// jclass clazz = (*env)->FindClass(env, “com/wonder/Info”);
// if (clazz == 0)
// return 0;
// //为新的java类对象obj分配内存
// jobject obj = (*env)->AllocObject(env, clazz);
// //发现类中的属性,如果失败,程序返回
// jfieldID fid_id = (*env)->GetFieldID(env, clazz, “id”, “I”);
// if (fid_id == 0)
// return 0;
// jfieldID fid_name = (*env)->GetFieldID(env, clazz, “name”,
// “Ljava/lang/String;”);
// if (fid_name == 0)
// return 0;
// (*env)->SetIntField(env, obj, fid_id, 1);
// //构造一个jString对象
// char * c_ptr_name = “I come from Native”;
//
// jstring jname = (*env)->NewStringUTF(env, c_ptr_name); //构造一个jstring对象
// (*env)->SetObjectField(env, obj, fid_name, jname);
// return obj;

Info_t* bar = malloc(sizeof(Info_t));
jclass clazz;
jfieldID fid;
//init the bar data of C
strcpy(bar->name,"Info");
bar->id = strlen(bar->name);

 // mapping bar of C to foo
clazz = (*env)->GetObjectClass(env, jobj);
if(clazz==0){
    return (-1);
}
fid = (*env)->GetFieldID(env, clazz, "id", "I");
(*env)->SetIntField(env,jobj,fid,bar->id);
fid = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
jstring name = (*env)->NewStringUTF(env, bar->name);
(*env)->SetObjectField(env,jobj,fid,name);
free(bar);
return 0;

}

int sum(int a, int b) {
return a + b;
}

ifdef __cplusplus

}

endif

4.创建Android.mk文件
LOCAL_PATH := (callmydir)include (CLEAR_VARS)
LOCAL_MODULE := TestNdk
LOCAL_SRC_FILES := com_wonder_Utils.c
include $(BUILD_SHARED_LIBRARY)
5.将com_wonder_Utils.c,com_wonder_Utils.h,Android.mk文件放到同一个jni文件夹下,使用ndk-build命令生成.so文件
6.在Android中使用时加载so库
static{
System.loadLibrary(“TestNdk”);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值