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 :=
(callmy−dir)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”);
}