JNI:在c代码中获得和直接修改java的string成员变量的值
jni c和java交互中,⼤部分数据类型都有对应,java中的string类型⽐较特殊,所以要⽤object。
java代码 StringTest1.java
public class StringTest1    {
public String s = new String("java string");
//声明c⽅法
public native void displayHelloWorld();
static{
//加载库名
System.loadLibrary("StringTest1");
}
public static void main(String[] args){
StringTest1 st1 = new StringTest1();
System.out.println("before call c:");
System.out.println(st1.s);
st1.displayHelloWorld();
System.out.println("after call c:");
System.out.println(st1.s);
}
}
命令⾏输⼊:
java StringTest1.java ⽣成StringTest1.java
javah StringTest1 ⽣成StringTest1.h
可以查看StringTest1.h⽂件,了解C中⽅法名
JNIEXPORT void JNICALL Java_StringTest1_displayHelloWorld
(JNIEnv *, jobject);
c代码 StringTest1.c
java int 类型 c中可以⽤int对应,GetIntFIeld()等
java的String类型 c中⽆对应类型,⽤object对应,如GetObjectField();
#include <jni.h>
#include "StringTest1.h"
#include <stdio.h>
JNIEXPORT void JNICALL
Java_StringTest1_displayHelloWorld(JNIEnv *env,jobject obj){
//得到java类名
jclass java_class = (*env)->GetObjectClass(env,obj);c++string类型
//string的类型签名有个分号;
jfieldID id_str = (*env)->GetFieldID(env,java_class,"s","Ljava/lang/String;");
/* //中间注释掉的这部分是c获得java的字符串
//强制类型转换,jobject转换为jstring
jstring str = (jstring)(*env)->GetObjectField(env,obj,id_str);
jsize len = (*env)->GetStringLength(env,str);
jchar j2c[len+1];
j2c[len] = L'\0';
/
/字符串str内容复制给j2c字符数组
(*env)->GetStringRegion(env,str,0,len,j2c);
*/
//以下实现 c修改java的string成员变量值
char* c2j = "c print string";
//字符数组c2j转换成jstring类型
jstring cstr = (*env)->NewStringUTF(env,c2j);
//设置java的string类型变量s的值
(*env)->SetObjectField(env,obj,id_str,cstr);
}
编译c⽂件
gcc -I/usr/java/jdk1.7.0_79/include/ -I/usr/java/jdk1.7.0_79/include/linux -shared -o libStringTest1.so StringTest1.c (1)需要jni.h和jni_md.h⽂件,所以加⼊-I/jdk路径/include和-I/jdk路径/include/linux
(2)-fPIC -shared -o 第⼀个可选,我没写,没遇到问题
java StringTest1
结果
before call c:
java string
after call c:
c print string
⼩技巧
1.java -s -p StringTest1 (包名.类名),得到每个⽅法的签名
Compiled from “StringTest1.java”
public class StringTest1 {
public java.lang.String s;
Signature: Ljava/lang/String;
public StringTest1();
Signature: ()V
public native void displayHelloWorld();
Signature: ()V
public static void main(java.lang.String[]);
Signature: ([Ljava/lang/String;)V
static {};
Signature: ()V
}
2. 查看你的jdk1.7/include/jni.h (第⼀个⽂件夹名字根据⾃⼰的版本具体名字)jni.h⽂件中有各个JNI⽅法的格式

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。