设为首页 加入收藏

TOP

Java中JNI的使用详解第四篇:C/C++中创建Java对象和String字符串对象及对字符串的操作方法(一)
2014-11-24 07:32:04 】 浏览:439
Tags:Java JNI 使用 详解 四篇 :C/C 创建 对象 String 字符串 操作 方法

首先来看一下C/C++中怎么创建Java对象:在JNIEnv中有两种方法是用来创建Java对象的:

第一种方法:

jobject NewObject(jclass clazz , jmethodID methodID, ....):

参数解释:

clazz:这个很简单,就是需要创建的Java对象的Class对象

methodID:这个是传递一个方法的ID,想一想Java对象在创建的时候,需要执行什么方法呢?对,没错那就是构造方法

第三个参数:是构造函数需要传入的参数值(默认的构造方法是不需要传入这个参数的)

所以我们在创建Java对象的时候之前要做的工作就是要获取这个对象的class对象,然后再获取该对象的构造方法,想要获取方法的id,就需要方法的签名,因为构造方法没有返回值,所以我们认为类的默认构造方法的返回值类型的签名始终是“()V”(因为默认的构造方法是没有参数的),方法的名称始终为“

例子:在C++中构造Java中的Date对象,并且调用它的getTime()方法打印当前时间

Java中的代码不需要改变,主要是C++代码中的改写:

[cpp]
  1. #include
  2. #include com_jni_demo_JNIDemo.h
  3. JNIEXPORT void JNICALL Java_com_jni_demo_JNIDemo_sayHello (JNIEnv * env, jobject obj)
  4. {
  5. //获取Java中Date对象的Class对象
  6. jclass clazz_date = env->FindClass(java/util/Date);
  7. //获取构造方法的id
  8. jmethodID mid_date = env->GetMethodID(clazz_date, ,()V);
  9. //生成Date对象
  10. jobject now = env->NewObject(clazz_date,mid_date);
  11. //获取Date对象中的getTime方法的id
  12. jmethodID mid_date_getTime = env->GetMethodID(clazz_date,getTime,()J);
  13. //调用getTime方法返回时间
  14. jlong time = env->CallLongMethod(now,mid_date_getTime);
  15. //打印时间,这里要注意的是不能使用cout输出了,因为cout并没有对__int64的输出进行重载,要输出的话用printf(%I64d,time);
  16. printf(%I64d,time);
  17. }

    编译成.dll文件,在Eclipse中运行结果如下:

    \

    这个输出的时间没有进行格式化处理。

    第二种方法:

    创建一个对象:就是用AllocObject

    使用函数AllocObject可以根据传入的jclass创建一个Java对象,但是他的状态时非初始化的,在是哟个这个对象之前绝对要用CallNonvirtualVoidMethod来调用该jclass的构造函数,这样就可以延迟构造函数的调用,这一部分用的很少,只做简单的说明:

    Java中的代码不做任何修改,C++代码中修改成如下:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. #include
    2. #include com_jni_demo_JNIDemo.h
    3. JNIEXPORT void JNICALL Java_com_jni_demo_JNIDemo_sayHello (JNIEnv * env, jobject obj)
    4. {
    5. //获取java中的Date对象
    6. jclass clazz_date = env->FindClass(java/util/Date);
    7. jmethodID methodID_str = env->GetMethodID(clazz_date, ,()V);
    8. jobject now = env->AllocObject(clazz_date);
    9. //调用构造方法
    10. env->CallNonvirtualVoidMethod(now,clazz_date,methodID_str);
    11. //获取Date对象中的getTime方法的id
    12. jmethodID mid_date_getTime = env->GetMethodID(clazz_date,getTime,()J);
    13. //调用getTime方法返回时间
    14. jlong time = env->CallLongMethod(now,mid_date_getTime);
    15. //打印时间,这里要注意的是不能使用cout输出了,因为cout并没有对__int64的输出进行重载,要输出的话用printf(%I64d,time);
    16. printf(%I64d,time);
    17. } 这种方式是很少用的!

      下面来看一下C/C++中如何操作Java中的字符串

      首先来看一下JNIEnv中的一些C++方法:

      1.获取字符串的长度:

      参数:j_msg:是一个jstring对象

      env->GetStringLength(jstring j_msg);

      2.将jstring对象拷贝到const jchar*指针字符串

      参数:j_msg:是一个jstring对象,start是拷贝字符串的开始位置,end是拷贝字符串的结束位置,jstr是目标指针字符串

      env->GetStringRegion(jstring j_msg , int start , int end , const jchar* jstr);

      3.生成一个jstring对象

      参数:jstr是字符串指针,size是字符串长度

      这个方法可以认为是将字符串指针jstr转化成字符串对象jstring

      env->NewString(const jchar* jstr , int size);

      4.将jstring对象转化成const jchar*字符串指针

      参数:j_msg是字符串对象

      env->GetStringChars(jstring j_msg , NULL);

      其对应的释放内存指针的方法:

      参数:j_msg是jstring对象,jstr是字符串指针

      ReleaseStringChars(jstring j_msg , const jchar* jstr);

      5.将jstring对象转化成const jchar*字符串指针

      参数:j_msg是字符串对象

      这个方法和第四个方法是一样的功能

      env->GetStringCritical(jstring j_msg , NULL);

      其对应的释放内存指针的方法:

      env->ReleaseStringCritical(jstring j_msg , const jchar* jstr);

      下面来看一下实例:在Java中定义一个String属性,通过控制台输入值,然后定义一个本地方法callCppFunction,在C++中这个方法的实现就是:获取到Java中这个字符串属性,将其进行倒序操作然后,然后再Java中输出:

      先来看一下Java中的代码:

      [java]
      1. package com.jni.demo;
      2. import java.io.BufferedReader;
      3. import java.io.InputStreamReader;
      4. public class JNIDemo {
      5. //定义一个本地方法
      6. public native void callCppFunction();
      7. /
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇用libevent实现一个小小的HTTP SE.. 下一篇java FTPClient下载多个文件

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目