您的位置:首页 > 编程语言 > Java开发

JNI中如何在本地代码中生成和操作Java的对象和字符串,并编写应用实例

2015-11-07 17:30 1516 查看
1、在C/C++本地代码中创建Java对象

主要使用的方法就是env->NewObject(jclass,jmethod)

例如:使用java中的java.util.Date对象的getTime()方法进行时间的输出

JNIEXPORT void JNICALL Java_jni_TestNative_sayhello(JNIEnv *env, jobject object){



//调用java中已经有的类,进行输出

//加载java中的Date类

jclass clazz_date=env->FindClass("java/util/Date");


//得到构造方法的ID

jmethodID date_id=env->GetMethodID(clazz_date,"<init>","()V");


//创建Date实例对象

jobject date=env->NewObject(clazz_date,date_id);

//调用Date中的getTime()方法

jmethodID gettime_id=env->GetMethodID(clazz_date,"getTime","()J");


//执行getTime()方法

jlong time=env->CallLongMethod(date,gettime_id);

cout<<time<<endl;

}



2、在C/C++本地代码中访问Java的String对象

例如加载代码中的:

package jni;

import java.util.Date;

public class TestNative {

public native void sayhello();

public String name="zhangsan";

public int number=10;

public double max(double num1,double num2){

return num1>num2?num1:num2;

}

// Father p=new Child();

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

System.loadLibrary("NativeCode");

TestNative tst=new TestNative();

tst.sayhello();

System.out.println(tst.number);

}

}



在C++文件中获取String name="zhangsan";

JNIEXPORT void JNICALL Java_jni_TestNative_sayhello(JNIEnv *env, jobject object){



//首先得到jclass对象,是后面得到属性和方法ID的基础

jclass clazz_TestNative=env->GetObjectClass(object);



//对java中字符串的调用

//得到那么的jfieldID

jfieldID name_id=env>GetFieldID(clazz_TestNative,"name","Ljava/lang/String;");

//得到该属性的值

jstring name=(jstring)env->GetObjectField(object,name_id);



const jchar* char_name=env->GetStringChars(name,NULL);

const char* name1=env->GetStringUTFChars(name,NULL); //zhangsan

cout<<char_name<<endl;

cout<<name1<<endl;



//对字符串进行截取

jchar * a=new jchar[10];

char* b=new char[100];

env->GetStringUTFRegion(name,0,3,b);

cout<<b<<endl;

env->GetStringRegion(name,0,3,a);

cout<<a <<endl;



//在不使用的时候进行本地字符串回收

env->ReleaseStringChars(name,char_name);

env->ReleaseStringUTFChars(name,name1);



//其中的jstring并不是一个字符串,我们需要对jstring进行相应的函数操作



1、const jchar *GetStringChars(jstring str, jboolean*isCopy)

将一个jstring对象,转换为(UTF-16)编码的宽字符串(jchar*)。

2、 const char *GetStringUTFChars(jstring str,jboolean *isCopy)

将一个jstring对象,转换为(UTF-8)编码的字符串(char*)。



这两个函数的参数中,第一个参数传入一个指向Java 中String对象的jstring引用。第二个参数传入的是一个jboolean的指针,其值可以为NULL、JNI_TRUE、JNI_FLASE。

如果为JNI_TRUE则表示开辟内存,然后把Java中的String拷贝到这个内存中,然后返回指向这个内存地址的指针。

如果为JNI_FALSE,则直接返回指向Java中String的内存指针。这时不要改变这个内存中的内容,这将破坏String在Java中始终是常量的规则。

如果是NULL,则表示不关心是否拷贝字符串。


使用这两个函数取得的字符,在不适用的时候,要分别对应的使用下面两个函数来释放内存。

3、RealeaseStringChars(jstring jstr, const jchar*str)

4、RealeaseStringUTFChars(jstring jstr, constchar* str)

第一个参数指定一个jstring变量,即要释放的本地字符串的资源

第二个参数就是要释放的本地字符串



3、在C/C++本地代码中创建Java的String对象

介绍一些方法

jstring string=env->newStringUTF(const char*);创建一个jstring对象

jstring string=env->newString(const jchar*);

jsize len=env->GetStringUTFLength(jstring);获取jstring 的长度

jszie len=env->GetStringLength(jstring);

jstring string=env->GetStringUTFChars(const char* );

jstring string=env->GetStringChars(const jchar*);字符串转为jstring

本地创建的字符串可以封装为jstring类型,然后传给java

package jni;

import java.util.Date;

public class TestNative {

public native void sayhello();

public String name="zhangsan";

public int number=10;

public double max(double num1,double num2){

return num1>num2?num1:num2;

}

// Father p=new Child();

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

System.loadLibrary("NativeCode");

TestNative tst=new TestNative();

tst.sayhello();

System.out.println(tst.number);

System.out.println(tst.name);

}

}



C++本地代码,可以修改name的值

JNIEXPORT void JNICALL Java_jni_TestNative_sayhello(JNIEnv *env, jobject object){



//首先得到jclass对象,是后面得到属性和方法ID的基础

jclass clazz_TestNative=env->GetObjectClass(object);



const char* subject="chinese";创建本地的字符串

jstring sub=env->NewStringUTF(subject);将本地的字符创封装为jstring


jsize len=env->GetStringUTFLength(sub);得到字符串的长度

jfieldID id_name1=env>GetFieldID(clazz_TestNative,"name","Ljava/lang/String;");

env->SetObjectField(object,id_name1,sub);


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