在java类JninameActivity(包名为com.ckl.jniname)中声明native接口:
private native String getJniString();
jstring Java_com_ckl_jniname_JninameActivity_getJniString(JNIEnv* env, jobject thiz) { // }如果使用的接口较多,这么长的函数名称将是比较麻烦的事情,这里使用宏定义的方法,可以减轻jni函数命名的工作量。
#include <jni.h> //定义包名+类名 #define CLASS com_ckl_jniname_JninameActivity //这里的宏一定要这样定义,才能合成出正确的函数名称 #define NAME3(CLASS3, FUNC3) Java_##CLASS3##_##FUNC3 #define NAME2(CLASS2, FUNC2) NAME3(CLASS2, FUNC2) #define NAME(FUNC) NAME2(CLASS, FUNC) //NAME(getJniString) 编译时将被替换为 Java_com_ckl_jniname_JninameActivity_getJniString jstring NAME(getJniString)(JNIEnv* env, jobject thiz) { return (*env)->NewStringUTF(env, "i am form Jni !"); } jstring NAME(getName)(JNIEnv* env, jobject thiz) { return (*env)->NewStringUTF(env, "i am Jack, "); } jstring NAME(getAge)(JNIEnv* env, jobject thiz) { return (*env)->NewStringUTF(env, "20 !"); }
#define NAME3(CLASS3, FUNC3) Java_##CLASS3##_##FUNC3 #define NAME2(CLASS2, FUNC2) NAME3(CLASS2, FUNC2) #define NAME(FUNC) NAME2(CLASS, FUNC)
JninameActivity.java package com.ckl.jniname; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class JninameActivity extends Activity { TextView mText1, mText2; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mText1 = (TextView)findViewById(R.id.text1); mText2 = (TextView)findViewById(R.id.text2); mText1.setText(getJniString()); mText2.setText(getName() + getAge()); } private native String getJniString(); private native String getName(); private native String getAge(); static { System.loadLibrary("jniname"); } }
工程代码:jniname.7z
当然,还有另外一种更常用的方法,
即在JNI_OnLoad()中使用(*env)->RegisterNatives()将需要用到的native接口注册好,
这样就不用按照上面的规则给jni函数取很长的名称了。
可以参考 http://blog.csdn.net/zhenyongyuan123/article/details/5862054