Jni中C++和Java的参数传递

来源:互联网 发布:淘宝店铺规划 编辑:程序博客网 时间:2024/05/21 08:02

转篇文章,这个解决困扰我几天的jni 传递java类做参数的问题



不说废话,直接进入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.hwin32/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对应得是javapackage,JniTest对应得是使 

用这个函数得java,jclass默认对应得也就是这个类,JNIEnv传递得是一个java得环境,jclass对应得就是函数 

名后得JNITest,后面得才是所有本地方法需要传递得数据 

// 

const char *str (js == 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 

jfieldID env->GetFieldID(clazz, "j", "I"); 

if (j == 0) return 0; 

int intFieldVal env->GetIntField(obj, j); 

//string 

jfieldID env->GetStaticFieldID(clazz, "t", "Ljava/lang/String;"); 

if (t == 0) return 1; 

jstring jstr (jstring) env->GetStaticObjectField(clazz, t); 

const char *str (jstr == 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位整型

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 

byte 

char 

short 

int 

long 

float 

double 

void 

objects对象 Lfully-qualified-class-name;L类名 

Arrays数组 [array-type [数组类型 

methods方法 (argument-types)return-type(参数类型)返回类型

 


原文:http://blog.sina.com.cn/s/blog_7eff0c2c0100sov4.html