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);
//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方法的格式