JNI 传递结构体参数

不说废话,直接进入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(参数类型)返回类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值