您的位置:首页 > 其它

JNI学习1

2013-04-10 15:20 134 查看
实践出真知,首先是从Hello JNI开始接触

目标文件包括:Hello.c Hello.class Hello.h Hello.java libHello.so;实现功能为在标准输出上打印Hello JNI

操作流程是:

编写Hello.java

用javac Hello.java 生成 Hello.class

用javah -jni Hello生成Hello.h

然后编写Hello.c,使用Gcc编译共享库libHello.so

最后调用java运行

共享库的编译命令为:gcc -shared -fPIC -I /usr/local/jdk1.6.0_30/include/ -I /usr/local/jdk1.6.0_30/include/linux/ -I /usr/local/ Hello.c -o libHello.so

运行命令为:java -Djava.library.path=. Hello

以下是主要文件代码

Hello.java

View Code

#include<stdio.h>
#include"Hello.h"

JNIEXPORT void JNICALL Java_basic_Hello_println (JNIEnv *env, jobject obj, jstring str) {
// get the object's class handle
jclass clsstr=(*env)->FindClass(env,"java/lang/String");
// create a string object in UTF-8 format
jstring strencode=(*env)->NewStringUTF(env,"utf-8");
// get the object's method handle, JNIenv, Object class, method name, method signature
// One can get the method signature by running "javap -s <class name>"
jmethodID mid=(*env)->GetMethodID(env,clsstr,"toCharArray","()[C");
// invoke the object method, JNIenv, java object, method ID, parameters
jcharArray barr=(jcharArray)(*env)->CallObjectMethod(env,str,mid,strencode);
jsize alen=(*env)->GetArrayLength(env,barr);

jboolean tt=JNI_TRUE;// or JNI_FALSE
jboolean *t=&tt;
// get a point to the header of a char array, JNIenv, the array, is copy
jchar* ba=(*env)->GetCharArrayElements(env,barr,t);

while(*ba!='\0')
printf("%c",*(ba++));
ba-=alen;
// release the reference of the array
(*env)->ReleaseCharArrayElements(env,barr,ba,0);
printf(" Hello JNI\n");
return;
}


最后运行修改后的Hello命令:java -Djava.library.path=. basic.Hello

运行结果:xxx Hello JNI

5、JNI中获取方法和变量域

大概需要如下三个步骤:

获取对象的类,例如

jclass clsstr=(*env)->FindClass(env,"java/lang/String");
jclass cls=(*env)->GetObjectClass(env,myobj);
等等


获取类中函数/变量域的ID(GetMethodID,GetFieldID),例如

/*
* 使用 javap -classpath <jar path> -s <class qualified name>  获取函数签名
*/
jmethodID mid=(*env)->GetMethodID(env,clsstr,"toCharArray","()[C");
/*
* JNI定义中有变量域的官方定义标签,JNI Data Structures
*/
jfieldID fid_msg=(*env)->GetFieldID(env,cls,"val","Z");


调用JNI中方法对函数/变量进行访问,例如

//变量访问
printf("%d\n",(*env)->GetBooleanField(env,myobj,fid_msg));
//方法调用
jcharArray barr=(jcharArray)(*env)->CallObjectMethod(env,str,mid,strencode);


Reference

Java基础知识——JNI入门介绍(下)

JNI使用规范详解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: