JNI的提高,Java类型和C(C++)类型转换源代码

时间:2021-10-10 15:36:41

JNI的环境准备就不说了, 网上大把大把的, 这里讲到的内容层次稍微深一点, 涉及Java和C的类型问题, 并配了实际案例的源代码。

 

JNI大体的流程是: Java端发起调用, 使C端的代码运行, 此时从Java侧传过来的对象, 可以在C端运行.

 

首先谈谈Java侧准备的代码:

1. 包含Native 方法的class

2. 通过JavaH, 将1中的Native方法生成C的函数原型. 这里完全可以不要, 只要你懂得以下规则:

  • 为了管理众多的Native方法(也可以说是区别Native方法), 需要C函数原型中夹带包名, 类名, 函数名
  • 由于C无法重载, 因此需要将这些包名冠在C函数名中.

3. 任意情况下Native 方法中的两个必带参数JNIEnv *env, jobject obj, 前者为JNI环境指针, 方便任意时刻,将Java对象转化为C变量, 以便我们处理。 后者为传递的当前Java对象(猜的, 要验证一下)

 

JNI的的问题一般限于以下类型:

参数传递

  参数如何从Java代码传递给C代码的,这里仅仅牵涉到几种基本类型:
  jstring, jboolean, jobject,jint,jdouble, 比较简单, JavaH编译出来的头文件就说名问题了.

参数转化

  传递过来j-参数,怎么像使用C代码一样使用?这里就有类型转化的问题。
  a>基本类型可以直接使用, 如double和jdouble可以互用。
  b> java对象使用
     对象有String对象和通用的Object对象。 处理的方式有点不同。
     不要再C/C++中调用Java的方法, C/C++处理完之后, 将数据对象传出就OK
     b1>String对象
        GetStringUTFChars取得从Java传入过来的String对象
        ReleaseStringUTFChars 用完之后需要释放
     b2>Object对象
        先得到对象的类句柄:
        jclass objectClass = (env)->FindClass("com/ostrichmyself/jni/Structure");
        然后取该类中, 需要的域句柄:
        jfieldID str = (env)->GetFieldID(objectClass,"nameString","Ljava/lang/String;");
jfieldID ival = (env)->GetFieldID(objectClass,"number","I");
        传入的jobject对象, 直接对各个域赋值。
        (env)->SetObjectField(theObjet,str,(env)->NewStringUTF("my name is D:"));
(env)->SetShortField(theObjet,ival,10);
        如果没有传入对象,而是新生成对象,则可以通过
        jobject myNewObjet = env->AllocObject(objectClass);

Java数组的处理

        用GetObjectArrayElement取传入的数组
        用NewObjectArray 构造一个数组

资源释放原则

   a1>C/C++ new的对象或者Malloc的对象,当然要由C/C++去释放
   a2>通过JNIEnv的方法new的对象, 如果不需要给Java使用,则必须释放
   a3>通过GetStringUTFChars转化从Java得到的String对象到UTF,需要开辟内存,使用完Char*时,
      务必释放内存,方法是:ReleaseStringUTFChars

基本涵盖了Java调用C++/C的语法,注意以下问题:

  • JNI没有两端, C调用java和java调用c实质都是一样的.也都称为JNI. 没有第二种称呼
  • 当C中存在耗时操作, 比如耗时的数据处理之后,gui更新, 可以通过java传递一个引用到C, 从而方便处理结束后调用, 这就是传说中的C调用java.

 

 

上述代码都在下面的链接中:


Native侧为C++代码(不是可编译工程, 但在vs2005下编译执行都已经通过)

 

 

 

Native侧为纯C代码(Cgwin 下的MakeFile)

 

 

Native侧如何调用Java对象方法代码(Cgwin 下的MakeFile)

 

 

thanks!

 

后记, 发现一偏IBM较新的技术文章, 非常不错, 推荐给大家:

 

《使用 Java Native Interface 的最佳实践》

 

http://www.ibm.com/developerworks/cn/java/j-jni/

 

资料从twitter上获取, 欢迎follow: @ostrichmyself

 

可以共享资料 ^-^