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

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++本地代码中访问JavaString对象

例如加载代码中的:

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++本地代码中创建JavaString对象

介绍一些方法

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);

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值