接着昨天的(JNI学习笔记(一)第一个JNI详细例子配图文)  

       

       今天学习一下JNI中的java语言与本地C/C++语言之间的映射;我们在进行实际编写程序的时候,函数的传参与函数的返回值是非常常见,也可是说是必须的事情了,今天就先从Java中的8大基本类型说起;

        Java与JNI中的基本类型映射表如下:

        

      

    下面我们看个例子,在Java中去调用有返回值的本地方法,本地方法返回一个字符串:

    java代码如下:    

package com.jiangqq.jni;  /**  *   * @author jiangqq  * <a href=http://blog.csdn.net/jiangqq781931404>CSND博客</a>  *  */ public class Test_Jni02 {  	/** 	 * 声明一个返回字符串的本地方法 	 * @param str 	 * @return 输入的字符串 	 */ 	public native String getLineStr(String str); 	 	public static void main(String[] args) {          Test_Jni02 test=new Test_Jni02();          String lineString=test.getLineStr("The input String :");          System.out.println(lineString); 	} } 

    我们进行转换头文件如下(com_jiangqq_jni_Test_Jni02.h):

     

/* DO NOT EDIT THIS FILE - it is machine generated */ #include "jni.h" /* Header for class com_jiangqq_jni_Test_Jni02 */  #ifndef _Included_com_jiangqq_jni_Test_Jni02 #define _Included_com_jiangqq_jni_Test_Jni02 #ifdef __cplusplus extern "C" { #endif /*  * Class:     com_jiangqq_jni_Test_Jni02  * Method:    getLineStr  * Signature: (Ljava/lang/String;)Ljava/lang/String;  */ JNIEXPORT jstring JNICALL Java_com_jiangqq_jni_Test_1Jni02_getLineStr   (JNIEnv *, jobject, jstring);  #ifdef __cplusplus } #endif #endif 

这个头文件中的

JNIEXPORT jstring JNICALL Java_com_jiangqq_jni_Test_1Jni02_getLineStr   (JNIEnv *, jobject, jstring);

 函数中有三个类型传入的参数:

  • JNIEnv *   :JNI函数的对象指针,很有用(重要),因为通过这个对象指针,就可以对Java那边的代码进行操作。JNIEnv的指针会被JNI传入到本地方法的实现函数中来对Java那部分的代码进行操作;
  • 看下调用图:


  • jobject    :这个参数具体代表着什么要取决于在被转换的本地方法是静态方法还是实例方法;如果该本地方法作为实例方法时,那么这个参数相当于对象本身(相当于this.);如果该本地方法作为静态方法时,那么这个参数相当于当前类;(重要)
  • jstring  这个就是传进来的字符串了(java的八大基本类型与C/C++的映射关系表在上面图上了,大家可以对照一下) 


  了解了以上这些,按照我们例子的要求,就要去实现本地方法返回字符串了,那还等什么,直接写代码呗;按照我们以前C语言的习惯,那还不简单。直接printf()与return该字符串呗,于是乎就出现之类下面的代码了:
错误代码: #include"com_jiangqq_jni_Test_Jni02.h" #include<stdio.h> JNIEXPORT jstring JNICALL Java_com_jiangqq_jni_Test_1Jni02_getLineStr 	(JNIEnv * env, jobject obj, jstring jstr) { 	printf("&s\n",jstr); 	return jstr; }
上面的代码,发现可以再VS上面进行编译,但是运行是不能生成dll,动态链接库文件的;
因为传过去的jstring格式和本地代码中的字符类型要进行转换,下面就直接写个很简单的本地代码的例子吧(明晚在学习稍微复杂的例子)

例子如下:
本地代码: #include"com_jiangqq_jni_Test_Jni02.h" #include<iostream> using namespace std;  JNIEXPORT jstring  JNICALL Java_com_jiangqq_jni_Test_1Jni02_getLineStr(JNIEnv *env, jobject obj, jstring jstr) { 	 	char *a="HelloWorld"; 	return (*env).NewStringUTF(a); 	  }
java代码如下:
package com.jiangqq.jni;  /**  *   * @author jiangqq  * <a href=http://blog.csdn.net/jiangqq781931404>CSND博客</a>  *  */ public class Test_Jni02 {  	/** 	 * 声明一个返回字符串的本地方法 	 * @param str 	 * @return 输入的字符串 	 */ 	public native String getLineStr(String str); 	 	public static void main(String[] args) {          Test_Jni02 test=new Test_Jni02();          String lineString=test.getLineStr("The input String :");                    System.out.println( "The input String :"+lineString);  	}   static   { 	  System.loadLibrary("nativeCode3");   } } 


接下来将要学习一下Java语言与本地语言的相互调用,继续看书学习了。。。