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);
}
主要使用的方法就是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);
}
相关文章推荐
- java课后作业6
- java 双重检查锁定及单例模式
- java练习——接口与继承
- java 二分查找
- Spring MVC 教程,快速入门,深入分析
- SpringMVC @RequestBody接收Json对象字符串
- [深入理解Java虚拟机]第十二章 Java内存模型与线程-Java内存模型
- java注释
- JavaWeb学习总结(一)——JavaWeb开发入门
- EditPlus配置Java环境,并实现简单的Hello Word!学习中
- 多线程指定ConcurrentHashMap定义了初始容量抛java.lang.OutOfMemoryError: Java heap space
- JavaWeb中的监听器
- eclipse bundle 32bit download address
- ANT教程之十四 Ant和Eclipse集成
- ANT教程之十三 Ant执行Java代码
- springmvc+datatables+mybatis分页
- Java的Scanner类中next()方法与nextLine()方法的区别
- Struts----5大组件
- Java递归实现删除树形结构的任一节点
- 浅析java中的hashcode()方法与equals()方法