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(参数类型)返回类型

你可能感兴趣的:(jni)