這一章節(jié)我們來練習(xí)練習(xí)jni訪問java涕癣,java訪問jni珊燎。
在擼碼之前先鋪一張數(shù)據(jù)類型對應(yīng)表
Java | JNI |
---|---|
boolean | jboolean |
byte | jbyte |
char | jchar |
short | jshort |
int | jint |
long | jlong |
float | jfloat |
double | jdouble |
JNI基本數(shù)據(jù)類型:
Java | JNI |
---|---|
boolean | jboolean |
byte | jbyte |
char | jchar |
short | jshort |
int | jint |
long | jlong |
float | jfloat |
double | jdouble |
引用類型:
Java | JNI |
---|---|
String | jstring |
Object | jobject |
非靜態(tài)函數(shù) java訪問JNI
C中代碼
JNIEXPORT jstring JNICALL Java_com_jni_demo_JniMain_getDataFromC1
(JNIEnv * env, jobject jcla){
char * ch = "Hello JNI NOT STAIC!";
return (*env)->NewStringUTF(env, ch);
}
這里如果是static參數(shù)就是jclass些侍,非靜態(tài)則為jboject
Java中代碼
//非靜態(tài)native方法
public native String getDataFromC1();
static {
System.loadLibrary("Jni_Demo");
}
/**
* @param args
*/
public static void main(String[] args) {
//非static native
JniMain jniMain = new JniMain();
System.out.println(jniMain.getDataFromC1());
}
訪問非靜態(tài)域 JNI訪問Java引用類型變量
簽名轉(zhuǎn)換:
數(shù)據(jù)類型 | 簽名 |
---|---|
boolean | Z |
byte | B |
char | C |
short | S |
int | I |
long | J |
float | F |
double | D |
void | V |
object | L開頭,然后以/分割包的完整類型,然后再加;比如說String的簽名就是Ljava/lang/String |
Array | 以[開頭嗡善,再加上數(shù)組元素類型的簽名,比如int[]学歧,簽名就是[I,再比如int[][]簽名就是[[I,object數(shù)組簽名就是[Ljava/lang/Object |
C中代碼
//訪問非靜態(tài)域罩引,并進(jìn)行修改
JNIEXPORT jstring JNICALL Java_com_jni_demo_JniMain_getvisitField
(JNIEnv * env, jobject jobj){
//1.得到j(luò)class
jclass jcla = (*env)->GetObjectClass(env,jobj);
//2.得到filed的屬性名稱
jfieldID fid = (*env)->GetFieldID(env, jcla, "javaStr", "Ljava/lang/String;");//最后一個(gè)參數(shù)為簽名
//3.獲取變量中對應(yīng)的值
jstring strOld = (*env)->GetObjectField(env, jobj, fid);
//4.將jstring轉(zhuǎn)成c語言對應(yīng)類型
char * strOldC = (*env)->GetStringUTFChars(env,strOld,NULL);
//char * mix = "after change ";
char mix[40] = "after change ";
//拼接新字符串
strcat(mix, strOldC);
//5.再將C語言對應(yīng)值轉(zhuǎn)換成jni類型
jstring new_str = (*env)->NewStringUTF(env, mix);
//將數(shù)據(jù)設(shè)置回去
(*env)->SetObjectField(env, jobj, fid, new_str);
//釋放占用內(nèi)存
(*env)->ReleaseStringChars(env, new_str, strOldC);
return new_str;
}
Java中代碼
public String javaStr = "kaka";
public native String getvisitField();
static {
System.loadLibrary("Jni_Demo");
}
/**
* @param args
*/
public static void main(String[] args) {
JniMain jniMain = new JniMain();
jniMain.getvisitField();
System.out.println(jniMain.javaStr);
}
訪問靜態(tài)域 JNI訪問Java基本類型變量
這里的操作跟上面差不多;
C中代碼
JNIEXPORT void JNICALL Java_com_jni_demo_JniMain_getChangeIntField
(JNIEnv * env, jobject jobj){
jclass jcla = (*env)->GetObjectClass(env, jobj);
jfieldID fid = (*env)->GetStaticFieldID(env, jcla, "javaInt", "I");
jint jintData = (*env)->GetStaticIntField(env, jcla, fid);
//可以看到c語言中的int typedef是jint撩满,所以可以直接操作jintData數(shù)據(jù)
jintData++;
//將數(shù)據(jù)設(shè)置回去
(*env)->SetStaticIntField(env, jobj, fid, jintData);
}
這里訪問靜態(tài)變量也就是調(diào)用jni接口的static方法蜒程,因?yàn)槭腔绢愋蜕鹉悖覍?yīng)在c語言中有對應(yīng)類型,所以這里不用轉(zhuǎn)換昭躺,直接將得到的jni類型進(jìn)行操作忌锯,妥妥的!
Java中代碼
public static int javaInt = 4;
public native void getChangeIntField();
static {
System.loadLibrary("Jni_Demo");
}
/**
* @param args
*/
public static void main(String[] args) {
JniMain jniMain = new JniMain();
jniMain.getChangeIntField();
System.out.println(javaInt);
}
好了這里2章的簡單jni入門就over了领炫,下一章節(jié)偶垮,將會(huì)在android studio中進(jìn)行jni開發(fā)。