版权声明:本文为博主原创文章,未经博主允许不得转载。
不说废话,直接进入jni之旅把,一下程序在vc+java方式得本地机器上运行通过.
首先调用jni得第一步.
在JAVA程序中,需要在类中声明所调用的库名称,如下:
static {
System.loadLibrary(“jnitest”);
}
在这里,库的扩展名字可以不用写出来,究竟是DLL还是SO,由系统自己判断。
其次用native声明本地方法
在这里因为需要,咱们声明如下:
public native static int intTest(int i);//测试传递一个基本数据int
public native static int stringTest(int i, String ts);//测试传递一个字符串
public native static int otestTest(int i, otest ts); //测试传递一个对象,对应c得结构体
public native static int bytesTest(int len,byte[] t); //测试传递一个数组
otest得定义:
class otest {
public int j;
public static String t;
public byte[] abyte;
}
后编译该JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就会生成C/C++的头文件。
第三,c/c++方面准备得工作.
将jdk安装目录得include目录下得jni.h和win32/jni_md.h拷贝到你c得库函数得目录下.
第四,编写c/c++程序
因为做测试,我得程序如下
//intTest
JNIEXPORT jint JNICALL Java_helli_JniTest_intTest
(JNIEnv *, jclass, jint j){
printf("this in put is int of:%d/n",j);
return j+2;
}
//stringTest
JNIEXPORT jint JNICALL Java_helli_JniTest_stringTest
(JNIEnv * env, jclass, jint j, jstring js){
//这里解释一点,注意函数名必须对应你javah生产得函数名,helli对应得是java得package,JniTest对应得是使
用这个函数得java累,jclass默认对应得也就是这个类,JNIEnv传递得是一个java得环境,jclass对应得就是函数
名后得JNITest,后面得才是所有本地方法需要传递得数据
//
const char *str = (js == 0) ? 0 : env->GetStringUTFChars(js,0 );
const char *t="朱磊";
printf("this in put is int of:%d--%s/n",j,t);
return j+2;
}
//otestTest
JNIEXPORT jint JNICALL Java_helli_JniTest_otestTest
(JNIEnv * env, jclass clazc, jint jint, jobject obj){
jclass clazz =env->FindClass("helli/otest");
//取int j
jfieldID j = env->GetFieldID(clazz, "j", "I");
if (j == 0) return 0;
int intFieldVal = env->GetIntField(obj, j);
//取string t
jfieldID t = env->GetStaticFieldID(clazz, "t", "Ljava/lang/String;");
if (t == 0) return 1;
jstring jstr = (jstring) env->GetStaticObjectField(clazz, t);
const char *str = (jstr == 0) ? 0 : env->GetStringUTFChars(jstr, 0);
//取byte[] abyte
jfieldID arrFieldId = env->GetFieldID(clazz, "abyte", "[B");
if (arrFieldId == 0) return 0;
jbyteArray jarr = (jbyteArray) env->GetObjectField(obj, arrFieldId);
jbyte *arr = env->GetByteArrayElements(jarr, 0);
char * c=(char *)arr;
add_0(c,4);//给byte数组加'/0'
printf("receive bytes string is %s/n",c);
// Set new values
env->SetIntField(obj, j, 888);
const char *cc="string ok";
env->SetStaticObjectField(clazz,t,env->NewStringUTF(cc));
arr=(jbyte *)cc;
env->SetByteArrayRegion(jarr,0,8,arr);
return jint+5;
}
//bytesTest
JNIEXPORT jint JNICALL Java_helli_JniTest_bytesTest
(JNIEnv * env, jclass clazz, jint len, jbyteArray jarr){
jbyte *arr = env->GetByteArrayElements(jarr, 0);
char * c=(char *)arr;
add_0(c,len);
printf("%s/n",c);
return j;
}
//给字符串加/0
void add_0(char * c,int len){
for (int i=0;i<len;i++) *c++;
*c++='/0';
}
译连接成库文件,本例是在WINDOWS下做的,生成的是DLL文件。并且名称要与JAVA中需要调用的一致,这里就
是jnitest.dll 。把goodluck.dll拷贝到java 运行得目录下或在system32目录下注册就可以了.用java运行这
个程序,你是否看到了你预期得运行结果?祝你好运.
附录1:类型映射表:
Java类型 本地类型 描述
boolean jboolean C/C++8位整型
byte jbyte C/C++带符号的8位整型
char jchar C/C++无符号的16位整型
short jshort C/C++带符号的16位整型
int jint C/C++带符号的32位整型
long jlong C/C++带符号的64位整型e
float jfloat C/C++32位浮点型
double jdouble C/C++64位浮点型
Object jobject 任何Java对象,或者没有对应java类型的对象
Class jclass Class对象
String jstring 字符串对象
Object[] jobjectArray 任何对象的数组
boolean[] jbooleanArray 布尔型数组
byte[] jbyteArray 比特型数组
char[] jcharArray 字符型数组
short[] jshortArray 短整型数组
int[] jintArray 整型数组
long[] jlongArray 长整型数组
float[] jfloatArray 浮点型数组
double[] jdoubleArray 双浮点型数组
※ JNI类型映射
附录2:域和方法符号表
Java 类型 符号
boolean Z
byte B
char C
short S
int I
long L
float F
double D
void V
objects对象 Lfully-qualified-class-name;L类名
Arrays数组 [array-type [数组类型
methods方法 (argument-types)return-type(参数类型)返回类型