NDK项目源码地址 :

— 第一个JNI示例程序下载GitHub – https://github.com/han1202012/NDKHelloworld.git

— Java传递参数给C语言实例程序 : GitHub – https://github.com/han1202012/NDKParameterPassing.git

C语言回调Java方法示例程序 : GitHub – https://github.com/han1202012/NDK_Callback.git

分析Log框架层JNI源码所需的Android底层文件 : CSDN – http://download.csdn.net/detail/han1202012/6905507

开发环境介绍 :

eclipse : adt-bundle-windows-x86-20130917

sdk : 版本 2.3.3

ndk : android-ndk-r9c-windows-x86.zip

cygwin : 所需组件 binutils , gcc , gcc-mingw , gdb , make;

javah : jdk6.0自带工具

javap : jdk6.0自带工具

**JNI 总结 : **

Java 调用 C 流程 :

a. 定义 Native 方法 : 在 shuliang.han.ndkparameterpassing.DataProvider.java 类中定义 Native 方法 public native int add(int x, int y);

b. 生成方法签名 : 进入 AndroidProject/bin/classes 目录, 使用 **javah **shuliang.han.ndkparameterpassing.DataProvider 命令, 便生成了头文件, 该头文件引用了 jni.h, 以及定义好了 对应的 Native 方法, 生成 JNIEXPORT jint JNICALL Java_shuliang_han_ndkparameterpassing_DataProvider_add (JNIEnv *, jobject, jint, jint);

c. 编写 Android.mk 文件 :

**[plain]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)
  <div>
    <embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_1">
    </embed>
  </div>
</div>
- LOCAL_PATH := $(call my-dir)

- 
- include $(CLEAR_VARS)

- 
- LOCAL_MODULE    := hello-jni

- LOCAL_SRC_FILES := hello-jni.c

- 
- include $(BUILD_SHARED_LIBRARY)

d. 生成 动态库 so 文件 : 进入 Android.mk 所在目录, 在该目录执行 ndk 下的 ndk-build 命令;

e. Java代码加载动态库 : 在 Java 代码中调用该类的类前面, 在类的一开始, 不在方法中, 加入 static{ System.loadLibrary(“hello”); } ;

一. JNI介绍

1. JNI引入

JNI概念 : Java本地接口,Java Native Interface, 它是一个协议, 该协议用来沟通Java代码和外部的本地C/C++代码, 通过该协议 Java代码可以调用外部的本地代码, 外部的C/C++ 代码可以调用Java代码;

C和Java的侧重 :

C语言 : C语言中最重要的是 函数 function;

Java语言 : Java中最重要的是 JVM, class类, 以及class中的方法;

C与Java如何交流 :

JNI规范 : C语言与Java语言交流需要一个适配器, 中间件, 即 JNI, JNI提供了一种规范;

C语言中调用Java方法 : 可以让我们在C代码中找到Java代码class中的方法, 并且调用该方法;

Java语言中调用C语言方法 : 同时也可以在Java代码中, 将一个C语言的方法映射到Java的某个方法上;

JNI桥梁作用 : JNI提供了一个桥梁, 打通了C语言和Java语言之间的障碍;

JNI中的一些概念 :

native : Java语言中修饰本地方法的修饰符, 被该修饰符修饰的方法没有方法体;

Native方法 : 在Java语言中被native关键字修饰的方法是Native方法;

JNI层 : Java声明Native方法的部分;

JNI函数 : JNIEnv提供的函数, 这些函数在jni.h中进行定义;

JNI方法 : Native方法对应的JNI层实现的 C/C++方法, 即在jni目录中实现的那些C语言代码;

2. Android中的应用程序框架

正常情况下的Android框架 : 最顶层Android的应用程序代码, 上层的应用层应用框架层 主要是Java代码, 中间有一层的Framework框架层代码是 C/C++代码, 通过Framework进行系统调用, 调用底层的库 和linux 内核;

使用JNI时的Android框架 : 绕过Framework提供的调用底层的代码, 直接调用自己写的C代码, 该代码最终会编译成为一个库, 这个库通过JNI提供的一个Stable的ABI 调用linux kernel;ABI是二进制程序接口 application binary interface.

纽带 : JNI是连接框架层 (Framework – C/C++) 和**应用框架层(Application Framework – Java)**的纽带;

JNI在Android中作用 : JNI可以调用本地代码库(即C/C++代码), 并通过 Dalvik虚拟机 与应用层应用框架层进行交互, Android中JNI代码主要位于应用层 和 应用框架层;

应用层 : 该层是由JNI开发, 主要使用标准JNI编程模型;

应用框架层 : 使用的是Android中自定义的一套JNI编程模型, 该自定义的JNI编程模型弥补了标准JNI编程模型的不足;

Android中JNI源码位置 : 在应用框架层中, 主要的JNI代码位于 framework/base目录下, 这些模块被编译成共享库之后放在 /system/lib 目录下;

NDK与JNI区别 :

NDK: NDK是Google开发的一套开发和编译工具集, 主要用于Android的JNI开发;

JNI : JNI是一套编程接口, 用来实现Java代码与本地的C/C++代码进行交互;

JNI编程步骤:

声明native方法 : 在Java代码中声明 native method()方法;

实现JNI的C/C++方法 : 在JNI层实现Java中声明的native方法, 这里使用javah工具生成带方法签名的头文件, 该JNI层的C/C++代码将被编译成动态库;

加载动态库 : 在Java代码中的静态代码块中加载JNI编译后的动态共享库;

.

3. JNI作用

JNI作用 :

扩展: JNI扩展了JVM能力, 驱动开发, 例如开发一个wifi驱动, 可以将手机设置为无限路由;

高效 : 本地代码效率高, 游戏渲染, 音频视频处理等方面使用JNI调用本地代码, C语言可以灵活操作内存;

复用 : 在文件压缩算法 7zip开源代码库, 机器视觉 openCV开放算法库 等方面可以复用C平台上的代码, 不必在开发一套完整的Java体系, 避免重复发明轮子;

特殊 : 产品的核心技术一般也采用JNI开发, 不易破解;

Java语言执行流程 :

编译字节码 : Java编译器编译 .java源文件, 获得.class 字节码文件;

装载类库 : 使用类装载器装载平台上的Java类库, 并进行字节码验证;

Java虚拟机 : 将字节码加入到JVM中, Java解释器 和 即时编译器 同时处理字节码文件, 将处理后的结果放入运行时系统;

调用JVM所在平台类库 : JVM处理字节码后, 转换成相应平台的操作, 调用本平台底层类库进行相关处理;

Java一次编译到处执行 : JVM在不同的操作系统都有实现, Java可以一次编译到处运行, 字节码文件一旦编译好了, 可以放在任何平台的虚拟机上运行;

.

二. NDK详解

1. 交叉编译库文件

C代码执行 : C代码被编译成库文件之后, 才能执行, 库文件分为动态库静态库 两种;

动态库 : unix环境下**.so 后缀的是动态库, windows环境下.dll 后缀**的是动态库; 动态库可以依赖静态库加载一些可执行的C代码;

静态库 :.a 后缀是静态库的扩展名;

库文件来源 : C代码 进行 编译 链接操作之后, 才会生成库文件, 不同类型的CPU 操作系统 生成的库文件是不一样;

CPU分类 : arm结构, 嵌入式设备处理器; x86结构, pc 服务器处理器; 不同的CPU指令集不同;

交叉编译 :windows x86编译出来的库文件可以在arm平台运行的代码;

交叉编译工具链 : Google提供的 NDK 就是交叉编译工具链, 可以在linux环境下编译出在arn平台下执行的二进制库文件;

NDK作用 : 是Google提供了交叉编译工具链, 能够在linux平台编译出在arm平台下执行的二进制库文件;

NDK版本介绍 : android-ndk-windows 是在windows系统中的cygwin使用的, android-ndk-linux 是在linux下使用的;

2. 部署NDK开发环境

(1) 下载Cygwin安装器

下载地址 : http://cygwin.com/setup-x86.exe , 这是下载器, 可以使用该下载器在线安装, 也可以将cygwin下载到本地之后, 在进行安装;

安装器使用 : Cygwin的下载, 在线安装, 卸载 等操作都有由该安装器进行;

本地文件安装 : 选择安装文件所在的目录, 然后选择所要安装的安装包;

在线安装 : 选择在线安装即可, 然后选择需要的安装包;

卸载 : windows上使用其它软件例如360, 控制面板中是无法卸载Cygwin的, 只能通过安装器来卸载;

(2) 安装Cygin

双击安装器 setup-x86.exe 下一步 :

选择安装方式 :

在线安装 : 直接下载, 然后安装;

下载安装文件 : 将安装文件下载下来, 可以随时安装, 注意安装文件也需要安装器来进行安装;

从本地文件安装 : 即使用下载的安装文件进行安装;

选择Cygwin安装位置 :

选择下载好安装文件位置 : 之前我下了一个完全版的Cygwin, 包括了所有的Cygwin组件, 全部加起来有5.23G, 下载速度很快, 使用网易的镜像, 基本可以全速下载;

选择需要安装Cygwin组件 : 这里我们只需要以下组件 : binutils , gcc , gcc-mingw , gdb , make , 不用下全部的组件;

之后点击下一步等待完成安装即可;

.

安装完之后, 打开bash命令窗口, 可以设置下显示的字体, 使用 make -version 查看是否安装成功 :

(3) Cygwin目录介绍

以下是Cygwin安装目录的情况 : 该安装目录就是所模拟的linux 的根目录;

对应的linux目录 : 这两个目录进行对比发现, 两个目录是一样的, Cygwin的安装目录就是 linux根目录;

cygdrive目录 : 该目录是Cygwin模拟出来的windows目录结构, 进入该目录后, 会发现windows的盘符目录, 通过该目录可以访问windows中的文件;

(4) 下载NDK工具

从Google的Android开发者官网上下载该工具, 注意NDK工具分类 : 下载地址 –http://developer.android.com/tools/sdk/ndk/index.html -;

windows版本NDK:android-ndk-r9c-windows-x86.zip (32位),android-ndk-r9c-windows-x86_64.zip (64位) 该版本是用在windows上的Cygwin下, 不能直接在windows上直接运行;

linux版本NDK :android-ndk-r9c-linux-x86.tar.bz2(32位) , android-ndk-r9c-linux-x86_64.tar.bz2 (64位) , 该版本直接在linux下执行即可;

在这里下载windows版本的NDK, 运行在Cygwin上;

(4) NDK环境介绍

NDK工具的文件结构 :

ndk-build脚本 : NDK build 脚本是 gun-make 的简单封装, gun-make 是编译C语言代码的工具, 该脚本执行的前提是linux环境下必须安装 make 程序;

**NDK安装在Cygwin中** : 将NDK压缩文件拷贝到Cygwin的根目录中, 解压 : android-ndk-r9c 目录就是NDK目录;





**执行以下NDK目录下的 ndk-build 命令** : ./ndk-build ;





**执行结果** :
**[plain]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)
    <div>
      <embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_2">
      </embed>
    </div>
  </div>
</div>


  - <span style=&#8221;font-family: &#8216;Courier New&#8217;;&#8221;>Android NDK: Could not find application project directory !
  
  - Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.
  
  - /android-ndk-r9c/build/core/build-local.mk:148: *** Android NDK: Aborting    。 停止。</span>
![](http://img.blog.csdn.net/20140130194048078)</div> 



  &nbsp;



# <a name="t12"></a>三. 开发第一个NDK程序

## <a name="t13"></a>1. 开发NDK程序流程

#### <a name="t14"></a>a. **创建Android工程**:



  首选创建一个Android工程, 在这个工程中进行JNI开发;



#### <a name="t15"></a>b. **声明native方法** :



  注意方法名使用 native 修饰, 没有方法体 和 参数, eg : public native String helloFromJNI();



#### <a name="t16"></a>c. **创建C文件** :



  在 工程根目录下创建 jni 目录, 然后创建一个c语言源文件, 在文件中引入 include <jni.h> , C语言方法声明格式 jstring Java_shuliang.han.ndkhelloworld_MainActivity_helloFromJNI(JNIEnv *env) , jstring 是 Java语言中的String类型, 方法名格式为 : Java_完整包名类名_方法名();





  &#8212; **JNIEnv参数** : 代表的是Java环境, 通过这个环境可以调用Java里面的方法;





  &#8212; **jobject参数** : 调用C语言方法的对象, thiz对象表示当前的对象, 即调用JNI方法所在的类;



#### <a name="t17"></a>d. **编写Android.mk文件** :



  如何写 查看文档, NDK根目录下有一个 documentation.html 文档, 点击该html文件就可以查看文档, 查看 Android.mk File 文档, 下面是该文档给出的 Android.mk示例 :



<div class="dp-highlighter bg_plain">
  <div class="bar">
    <div class="tools">
      **[plain]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

      
      <div>
        <embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_3">
        </embed>
      </div>
    </div>
  </div>
  
  
    - LOCAL_PATH := $(call my-dir)
    
    - 
    - include $(CLEAR_VARS)
    
    - 
    - LOCAL_MODULE    := hello-jni
    
    - LOCAL_SRC_FILES := hello-jni.c
    
    - 
    - include $(BUILD_SHARED_LIBRARY)
    
  
</div>



  &#8212; **LOCAL_PATH** : 代表mk文件所在的目录;





  &#8212; **include $(CLEAR_VARS)** : 编译工具函数, 通过该函数可以进行一些初始化操作;





  &#8212; **LOCAL_MODULE** : 编译后的 .so 后缀文件叫什么名字;





  &#8212; **LOCAL_SRC_FILES**: 指定编译的源文件名称;





  &#8212; **include $(BUILD_SHARED_LIBRARY)** : 告诉编译器需要生成动态库;



#### <a name="t18"></a>e. **NDK编译生成动态库** :



  进入 cygdrive 找到windows目录下对应的文件, 编译完成之后, 会**自动生成so文件并放在libs目录下**, 之后就可以在Java中调用C语言方法了;



#### <a name="t19"></a>f. **Java中加载动态库** :



  在Java类中的静态代码块中使用System.LoadLibrary()方法加载编译好的 .so 动态库;





  **NDK平台版本** : NDK脚本随着 android-sdk 版本不同, 执行的脚本也是不同的, 不同平台会引用不同的头文件, 编译的时候一定注意 sdk 与 ndk 版本要一致;





  **so文件在内存中位置** : apk文件安装到手机上之后, .so动态库文件存在在 data/安装目录/libs 目录下;



## <a name="t20"></a>2. 开发实例

<div>
</div>

<div>
  **按照上面的步骤进行开发**
</div>

<div>
</div>

<div>
</div>

### <a name="t21"></a>(1) 创建Android工程

<div>
</div>

<div>
  **Android工程版本** : 创建一个Android工程,**minSdk 为 7 即 android-2.1**, 编译使用的**sdk为 10 即 android-2.3.3** ;
</div>

<div>
  <div class="dp-highlighter bg_html">
    <div class="bar">
      <div class="tools">
        **[html]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

        
        <div>
          <embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_4">
          </embed>
        </div>
      </div>
    </div>
    
    
      - <span class="tag"><</span><span class="tag-name">uses-sdk</span>
      
      - <span class="attribute">android:minSdkVersion</span>=<span class="attribute-value">&#8220;7&#8221;</span>
      
      - <span class="attribute">android:targetSdkVersion</span>=<span class="attribute-value">&#8220;10&#8221;</span> <span class="tag">/></span>
      
    
  </div>
</div>

<div>
  **NDK编译原则** : 编译NDK动态库是**按照最小版本进行编译**, 选择编译的平台的时候, 会选择 NDK 7 平台进行编译;
</div>

<div>
</div>

<div>
  ![](http://img.blog.csdn.net/20140130221252312)      ![](http://img.blog.csdn.net/20140130221301250)
</div>

<div>
</div>

### <a name="t22"></a>(2) 声明native方法

<div>
</div>

<div>
  **声明native方法, 注意该方法没有方法体 和 参数, 如下** :
</div>

<div>
</div>

<div>
  <div class="dp-highlighter bg_java">
    <div class="bar">
      <div class="tools">
        **[java]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

        
        <div>
          <embed id="ZeroClipboardMovie_5" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_5">
          </embed>
        </div>
      </div>
    </div>
    
    
      - <span class="comment">/*</span>
      
      - <span class="comment"> * 声明一个native方法</span>
      
      - <span class="comment"> * 这个方法在Java中是没有实现的, 没有方法体</span>
      
      - <span class="comment"> * 该方法需要使用C语言编写</span>
      
      - <span class="comment"> */</span>
      
      - <span class="keyword">public</span> <span class="keyword">native</span> String helloFromJNI();
      
    
  </div>
  
  

    .
  

  
  

    **作者** : **万境绝尘 **
  

  
  

    **转载请注明出处** : [**http://blog.csdn.net/shulianghan/article/details/18964835**](http://blog.csdn.net/shulianghan/article/details/18964835)
  

  
  

    .
  

</div>

### <a name="t23"></a>(3) 创建C文件

<div>
</div>

<div>
  **引入头文件**: 首先要包含头文件 jni.h, 该**头文件位置**定义在 android-ndk-r9c\platforms\android-5\arch-arm\usr\include目录下的 jni.h, 下面是该头文件中定义的一些方法, 包括本项目中使用的 NewString 方法;
</div>

<div>
  <div class="dp-highlighter bg_cpp">
    <div class="bar">
      <div class="tools">
        **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

        
        <div>
          <embed id="ZeroClipboardMovie_6" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_6">
          </embed>
        </div>
      </div>
    </div>
    
    
      - jstring     (*NewString)(JNIEnv*, <span class="keyword">const</span> jchar*, jsize);
      
      - jsize       (*GetStringLength)(JNIEnv*, jstring);
      
      - <span class="keyword">const</span> jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);
      
      - <span class="keyword">void</span>        (*ReleaseStringChars)(JNIEnv*, jstring, <span class="keyword">const</span> jchar*);
      
      - jstring     (*NewStringUTF)(JNIEnv*, <span class="keyword">const</span> <span class="datatypes">char</span>*);
      
      - jsize       (*GetStringUTFLength)(JNIEnv*, jstring);
      
    
  </div>
</div>

<div>
</div>

<div>
  **调用Java类型** : C中调用Java中的String类型为 jstring;
</div>

<div>
</div>

<div>
  **C语言方法名规则** : Java_完整包名类名_方法名(JNIEnv *env, jobject thiz), 注意完整的类名包名中包名的点要用 _ 代替;
</div>

<div>
</div>

<div>
  **参数介绍** : C语言方法中有两个重要的参数, JNIEnv *env, jobject thiz ;
</div>

<div>
  &#8212; **JNIEnv参数** : 该参数代表Java环境, 通过这个环境可以调用Java中的方法;
</div>

<div>
  &#8212; **jobject参数** : 该参数代表调用jni方法的类, 在这里就是MainActivity;
</div>

<div>
</div>

<div>
  **调用jni.h中的NewStringUTF方法** : 该方法的作用是在C语言中创建一个Java语言中的String类型对象, jni.h中是这样定义的 jstring (*NewStringUTF)(JNIEnv*, const char*), JNIEnv 结构体中包含了 NewStringUTF 函数指针, 通过 JNIEnv 就可以调用这个方法;
</div>

<div>
</div>

<div>
  **C语言文件源码** :
</div>

<div>
  <div class="dp-highlighter bg_cpp">
    <div class="bar">
      <div class="tools">
        **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

        
        <div>
          <embed id="ZeroClipboardMovie_7" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_7">
          </embed>
        </div>
      </div>
    </div>
    
    
      - <span class="preprocessor">#include <jni.h></span>
      
      - 
      - <span class="comment">/*</span>
      
      - <span class="comment"> * 方法名称规定 : Java_完整包名类名_方法名()</span>
      
      - <span class="comment"> * JNIEnv 指针</span>
      
      - <span class="comment"> *</span>
      
      - <span class="comment"> * 参数介绍 :</span>
      
      - <span class="comment"> * env : 代表Java环境, 通过这个环境可以调用Java中的方法</span>
      
      - <span class="comment"> * thiz : 代表调用JNI方法的对象, 即MainActivity对象</span>
      
      - <span class="comment"> */</span>
      
      - jstring Java_shuliang_han_ndkhelloworld_MainActivity_helloFromJNI(JNIEnv *env, jobject thiz)
      
      - {
      
      - <span class="comment">/*</span>
      
      - <span class="comment">     * 调用 android-ndk-r9c\platforms\android-8\arch-arm\usr\include 中jni.h中的方法</span>
      
      - <span class="comment">     * jni.h 中定义的方法  jstring (*NewStringUTF)(JNIEnv*, const char*); </span>
      
      - <span class="comment">     */</span>
      
      - <span class="keyword">return</span> (*env)->NewStringUTF(env, <span class="string">&#8220;hello world jni&#8221;</span>);
      
      - }
      
    
  </div>
  
  <div>
  </div>
  
  <div>
  </div>
  
  ### <a name="t24"></a>(4) 编写Android.mk文件
</div>

<div>
</div>

<div>
</div>

<div>
  **查询NDK文档** : NDK的文档在NDK工具根目录下, 点击 documentation.html 文件, 就可以在浏览器中打开NDK文档;
</div>

<div>
</div>

<div>
  **上面的开发流程中详细的介绍了Android.mk 五个参数的详细用处, 这里直接给出源码** :
</div>

<div>
  <div class="dp-highlighter bg_plain">
    <div class="bar">
      <div class="tools">
        **[plain]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

        
        <div>
          <embed id="ZeroClipboardMovie_8" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_8">
          </embed>
        </div>
      </div>
    </div>
    
    
      - LOCAL_PATH := $(call my-dir)
      
      - 
      - include $(CLEAR_VARS)
      
      - 
      - LOCAL_MODULE    := hello
      
      - LOCAL_SRC_FILES := hello.c
      
      - 
      - include $(BUILD_SHARED_LIBRARY)
      
    
  </div>
  
  ### <a name="t25"></a>(5) 编译NDK动态库
</div>

<div>
</div>

<div>
</div>

<div>
  **进入Cygwin相应目录** : 从Cygwin中的cygdrive 中进入windows的工程jni目录 ;
</div>

<div>
  ![](http://img.blog.csdn.net/20140130223434359)

</div>

<div>
  **编译hello.c文件** : 注意Android.mk文件 与 hello.c 文件在同一目录中;
</div>

<div>
  ![](http://img.blog.csdn.net/20140130224601328)
</div>

<div>
</div>

<div>
  **编译完成后的情况** : 编译完之后 会成成一个obj文件, 在obj文件中会生成 libhello.so, 系统会**自动将该 so后缀文件放在libs目录下**;
</div>

<div>
  ![](http://img.blog.csdn.net/20140130224720812)
</div>

<div>
</div>

<div>
</div>

<div>
</div>

### <a name="t26"></a>(6) Java中加载动态库

<div>
</div>

<div>
  **静态代码块中加载** : Java中在静态代码块中加载库文件, 调用 System.loadLibrary(&#8220;hello&#8221;) 方法,**注意 libs中的库文件名称为 libhello.so**,**我们加载的时候 将 lib 去掉**, 只取hello 作为动态库名称, 这是规定的;
</div>

<div>
  <div class="dp-highlighter bg_java">
    <div class="bar">
      <div class="tools">
        **[java]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

        
        <div>
          <embed id="ZeroClipboardMovie_9" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_9">
          </embed>
        </div>
      </div>
    </div>
    
    
      - <span class="comment">//静态代码块加载C语言库文件</span>
      
      - <span class="keyword">static</span>{
      
      - System.loadLibrary(<span class="string">&#8220;hello&#8221;</span>);
      
      - }
      
    
  </div>
  
  <div>
  </div>
  
  <div>
  </div>
  
  ### <a name="t27"></a>(7) 其它源码
</div>

<div>
</div>

<div>
  **MainActivity源码** :
</div>

<div>
  <div class="dp-highlighter bg_java">
    <div class="bar">
      <div class="tools">
        **[java]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

        
        <div>
          <embed id="ZeroClipboardMovie_10" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_10">
          </embed>
        </div>
      </div>
    </div>
    
    
      - <span class="keyword">package</span> shuliang.han.ndkhelloworld;
      
      - 
      - <span class="keyword">import</span> android.app.Activity;
      
      - <span class="keyword">import</span> android.os.Bundle;
      
      - <span class="keyword">import</span> android.view.View;
      
      - <span class="keyword">import</span> android.widget.Toast;
      
      - 
      - <span class="keyword">public</span> <span class="keyword">class</span> MainActivity <span class="keyword">extends</span> Activity {
      
      - 
      - <span class="comment">//静态代码块加载C语言库文件</span>
      
      - <span class="keyword">static</span>{
      
      - System.loadLibrary(<span class="string">&#8220;hello&#8221;</span>);
      
      - }
      
      - 
      - <span class="comment">/*</span>
      
      - <span class="comment">     * 声明一个native方法</span>
      
      - <span class="comment">     * 这个方法在Java中是没有实现的, 没有方法体</span>
      
      - <span class="comment">     * 该方法需要使用C语言编写</span>
      
      - <span class="comment">     */</span>
      
      - <span class="keyword">public</span> <span class="keyword">native</span> String helloFromJNI();
      
      - 
      - <span class="annotation">@Override</span>
      
      - <span class="keyword">protected</span> <span class="keyword">void</span> onCreate(Bundle savedInstanceState) {
      
      - <span class="keyword">super</span>.onCreate(savedInstanceState);
      
      - setContentView(R.layout.activity_main);
      
      - System.out.println(helloFromJNI());
      
      - }
      
      - 
      - <span class="keyword">public</span> <span class="keyword">void</span> onClick(View view) {
      
      - <span class="comment">//点击按钮显示从jni调用得到的字符串信息</span>
      
      - Toast.makeText(getApplicationContext(), helloFromJNI(), <span class="number">1</span>).show();
      
      - }
      
      - 
      - }
      
    
  </div>
  
  

    **XML布局文件** :</div> 
    
    <div>
      <div class="dp-highlighter bg_html">
        <div class="bar">
          <div class="tools">
            **[html]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

            
            <div>
              <embed id="ZeroClipboardMovie_11" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_11">
              </embed>
            </div>
          </div>
        </div>
        
        
          - <span class="tag"><</span><span class="tag-name">RelativeLayout</span> <span class="attribute">xmlns:android</span>=<span class="attribute-value">&#8220;http://schemas.android.com/apk/res/android&#8221;</span>
          
          - <span class="attribute">xmlns:tools</span>=<span class="attribute-value">&#8220;http://schemas.android.com/tools&#8221;</span>
          
          - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;match_parent&#8221;</span>
          
          - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;match_parent&#8221;</span>
          
          - <span class="attribute">android:paddingBottom</span>=<span class="attribute-value">&#8220;@dimen/activity_vertical_margin&#8221;</span>
          
          - <span class="attribute">android:paddingLeft</span>=<span class="attribute-value">&#8220;@dimen/activity_horizontal_margin&#8221;</span>
          
          - <span class="attribute">android:paddingRight</span>=<span class="attribute-value">&#8220;@dimen/activity_horizontal_margin&#8221;</span>
          
          - <span class="attribute">android:paddingTop</span>=<span class="attribute-value">&#8220;@dimen/activity_vertical_margin&#8221;</span>
          
          - <span class="attribute">tools:context</span>=<span class="attribute-value">&#8220;.MainActivity&#8221;</span> <span class="tag">></span>
          
          - 
          - <span class="tag"><</span><span class="tag-name">Button</span>
          
          - <span class="attribute">android:id</span>=<span class="attribute-value">&#8220;@+id/bt&#8221;</span>
          
          - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span>
          
          - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span>
          
          - <span class="attribute">android:onClick</span>=<span class="attribute-value">&#8220;onClick&#8221;</span>
          
          - <span class="attribute">android:text</span>=<span class="attribute-value">&#8220;显示JNI返回的字符串&#8221;</span> <span class="tag">/></span>
          
          - 
          - <span class="tag"></</span><span class="tag-name">RelativeLayout</span><span class="tag">></span>
          
        
      </div>
      
      ### <a name="t28"></a>(8) 将源码上传到GitHub中
    </div>
    
    <div>
    </div>
    
    <div>
    </div>
    
    <div>
      在上一篇博客 [http://blog.csdn.net/shulianghan/article/details/18812279](http://blog.csdn.net/shulianghan/article/details/18812279) 中对GitHub用法进行了详解;
    </div>
    
    <div>
    </div>
    
    <div>
      **在GitHub上创建工程** :
    </div>
    
    <div>
    </div>
    
    <div>
      **项目地址**
    </div>
    
    <div>
      &#8212; **HTTP**: https://github.com/han1202012/NDKHelloworld.git
    </div>
    
    <div>
      &#8212; **SSH** : git@github.com:han1202012/NDKHelloworld.git
    </div>
    
    <div>
    </div>
    
    <div>
      **生成的命令** :

      
      <div class="dp-highlighter bg_plain">
        <div class="bar">
          <div class="tools">
            **[plain]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

            
            <div>
              <embed id="ZeroClipboardMovie_12" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_12">
              </embed>
            </div>
          </div>
        </div>
        
        
          - touch README.md
          
          - git init
          
          - git add README.md
          
          - git commit -m &#8220;first commit&#8221;
          
          - git remote add origin git@github.com:han1202012/NDKHelloworld.git
          
          - git push -u origin master
          
        
      </div>
      
      

        **打开 Git Bash 命令行窗口** :</div> 
        
        <div>
          &#8212; **从GitHub上克隆项目到本地** : git clone git@github.com:han1202012/NDKHelloworld.git , 注意克隆的时候直接在仓库根目录即可, 不用再创建项目根目录 ;
        </div>
        
        <div>
          ![](http://img.blog.csdn.net/20140130232116609)
        </div>
        
        <div>
          &#8212; **添加文件** : git add ./* , 将目录中所有文件添加;
        </div>
        
        <div>
          ![](http://img.blog.csdn.net/20140130232554281)

查看状态 : git status ;

        <div>
          ![](http://img.blog.csdn.net/20140130232317546)
        </div>
        
        <div>
          &#8212; **提交缓存** : git commit -m &#8216;提交&#8217;;
        </div>
        
        <div>
          ![](http://img.blog.csdn.net/20140130232423812)

提交到远程GitHub仓库 : git push -u origin master ;

        <div>
          ![](http://img.blog.csdn.net/20140130232509203)
        </div>
        
        <div>
        </div>
        
        <div>
          **GitHub项目** :
        </div>
        
        <div>
          ![](http://img.blog.csdn.net/20140130232709500)
        </div>
        
        <div>
        </div>
        
        <div>
        </div>
        
        <div>
        </div>
        
        <div>
        </div>
        
        ## <a name="t29"></a>3. 项目讲解
        
        <div>
        </div>
        
        ### <a name="t30"></a>(1) Android.mk文件讲解
        
        <div>
        </div>
        
        <div>
          **Android.mk文件内容** :
        </div>
        
        <div>
        </div>
        
        <div>
          <div class="dp-highlighter bg_plain">
            <div class="bar">
              <div class="tools">
                **[plain]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                
                <div>
                  <embed id="ZeroClipboardMovie_13" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_13">
                  </embed>
                </div>
              </div>
            </div>
            
            
              - LOCAL_PATH := $(call my-dir)
              
              - 
              - include $(CLEAR_VARS)
              
              - 
              - LOCAL_MODULE    := hello
              
              - LOCAL_SRC_FILES := hello.c
              
              - 
              - include $(BUILD_SHARED_LIBRARY)
              
            
          </div>
          
          <div>
          </div>
          
          <div>
            **获取当前文件内容** : $(call my-dir) 是编译器中的宏方法, 调用该宏方法, 就会**返回前的目录路径**;
          </div>
          
          <div>
            **赋值符号** : &#8221; := &#8221; 是**赋值符号**, 第一句话 是 返回当前文件所在的当前目录, 并将这个目录路径赋值给 LOCAL_PATH;
          </div>
          
          <div>
            **初始化编译模块参数** : $(CLEAR_VARS) 作用是将编译模块的参数初始化, LOCAL_MODULE LOCAL_SRC_FILES 也是这样的参数;
          </div>
          
          

            **指定编译模块** : LOCAL_MODULE    := hello , 指定编译后的 so 文件名称, 编译好之后系统会在该名称前面加上 &#8220;lib&#8221;, 后缀加上 &#8220;.so&#8221;;</div> 
            
            <div>
              **指定编译源文件** : LOCAL_SRC_FILES := hello.c 告诉编译系统源文件, 如果有多个文件那么就依次写在后面即可;
            </div>
            
            <div>
              **编译成静态库** : include $(BUILD_SHARED_LIBRARY), 作用是高速系统, 编译的结果编译成 .so 后缀的静态库;
            </div>
            
            <div>
            </div>
            
            <div>
              **静态库引入** : NDK的platform中有很多 &#8220;.a&#8221; 结尾的动态库, 我们编译动态库的时候, 可以将一些静态库引入进来;
            </div>
            
            <div>
            </div>
            
            <div>
            </div>
            
            ### <a name="t31"></a>(2) 自动生成方法签名
            
            <div>
            </div>
            
            <div>
            </div>
            
            <div>
              **使用javah工具** : 在C中实现Java调用的jni方法, 方法的签名很复杂, 需要将完整的包名类名方法名都要使用 &#8220;_&#8221; 连接起来, 很麻烦, jdk提供的生成签名方法的工具;
            </div>
            
            <div>
            </div>
            
            <div>
              **遗留问题** : 目前查到的方法是 在bin目录下 执行 javah -jni 包名类名 命令, 但是执行不成功, 暂时没找到解决方案;
            </div>
            
            <div>
              &#8212;** Android中会自动生成** .class文件吗, 没发现啊, PY人!
            </div>
            
            <div>
              ![](http://img.blog.csdn.net/20140131220806843)
            </div>
            
            <div>
            </div>
            
            <div>
              **解决问题** : 在jni目录下存在classes目录, 但是这个目录在eclipse中不显示, 这里我们要注意;
            </div>
            
            <div>
              ![](http://img.blog.csdn.net/20140207202154937)
            </div>
            
            <div>
            </div>
            
            <div>
              **在Cygwin中使用 javah 命令即可** :
            </div>
            
            <div>
              ![](http://img.blog.csdn.net/20140207185534812)
            </div>
            
            <div>
              **生成的头文件** : shuliang_han_ndkparameterpassing_DataProvider.h;
            </div>
            
            <div>
              <div class="dp-highlighter bg_cpp">
                <div class="bar">
                  <div class="tools">
                    **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                    
                    <div>
                      <embed id="ZeroClipboardMovie_14" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_14">
                      </embed>
                    </div>
                  </div>
                </div>
                
                
                  - <span class="comment">/* DO NOT EDIT THIS FILE &#8211; it is machine generated */</span>
                  
                  - <span class="preprocessor">#include <jni.h></span>
                  
                  - <span class="comment">/* Header for class shuliang_han_ndkparameterpassing_DataProvider */</span>
                  
                  - 
                  - <span class="preprocessor">#ifndef _Included_shuliang_han_ndkparameterpassing_DataProvider</span>
                  
                  - <span class="preprocessor">#define _Included_shuliang_han_ndkparameterpassing_DataProvider</span>
                  
                  - <span class="preprocessor">#ifdef __cplusplus</span>
                  
                  - <span class="keyword">extern</span> <span class="string">&#8220;C&#8221;</span> {
                  
                  - <span class="preprocessor">#endif</span>
                  
                  - <span class="comment">/*</span>
                  
                  - <span class="comment"> * Class:     shuliang_han_ndkparameterpassing_DataProvider</span>
                  
                  - <span class="comment"> * Method:    add</span>
                  
                  - <span class="comment"> * Signature: (II)I</span>
                  
                  - <span class="comment"> */</span>
                  
                  - JNIEXPORT jint JNICALL Java_shuliang_han_ndkparameterpassing_DataProvider_add
                  
                  - (JNIEnv *, jobject, jint, jint);
                  
                  - 
                  - <span class="comment">/*</span>
                  
                  - <span class="comment"> * Class:     shuliang_han_ndkparameterpassing_DataProvider</span>
                  
                  - <span class="comment"> * Method:    sayHelloInc</span>
                  
                  - <span class="comment"> * Signature: (Ljava/lang/String;)Ljava/lang/String;</span>
                  
                  - <span class="comment"> */</span>
                  
                  - JNIEXPORT jstring JNICALL Java_shuliang_han_ndkparameterpassing_DataProvider_sayHelloInc
                  
                  - (JNIEnv *, jobject, jstring);
                  
                  - 
                  - <span class="comment">/*</span>
                  
                  - <span class="comment"> * Class:     shuliang_han_ndkparameterpassing_DataProvider</span>
                  
                  - <span class="comment"> * Method:    intMethod</span>
                  
                  - <span class="comment"> * Signature: ([I)[I</span>
                  
                  - <span class="comment"> */</span>
                  
                  - JNIEXPORT jintArray JNICALL Java_shuliang_han_ndkparameterpassing_DataProvider_intMethod
                  
                  - (JNIEnv *, jobject, jintArray);
                  
                  - 
                  - <span class="preprocessor">#ifdef __cplusplus</span>
                  
                  - }
                  
                  - <span class="preprocessor">#endif</span>
                  
                  - <span class="preprocessor">#endif</span>
                  
                
              </div>
            </div>
            
            <div>
            </div>
            
            <div>
              .
            </div>
            
            <div>
            </div>
            
            <div>
            </div>
            
            ### <a name="t32"></a>(3) NDK开发中乱码问题
            
            <div>
            </div>
            
            <div>
              **解决乱码思路** : C语言编译的时候用的是 ISO-8859-1 码表进行编码, 如果我们使用C语言jni开发, 需要进行转码操作;
            </div>
            
            <div>
              &#8212; 将ISO-8859-1转为UTF-8字符: String string = new String(str.getBytes(&#8220;iso8859-1&#8221;), &#8220;UTF-8&#8221;);
            </div>
            
            <div>
            </div>
            
            <div>
            </div>
            
            <div>
              示例 :
            </div>
            
            <div>
            </div>
            
            <div>
              **添加中文jni调用** : 将jni中的hello.c 中返回的字符串修改为中文, 重新编译 .so 静态库文件;
            </div>
            
            <div>
              &#8212; **修改后的hello.c文件如下** : 只改变了返回的字符串, 添加了中文;
            </div>
            
            <div>
              <div class="dp-highlighter bg_cpp">
                <div class="bar">
                  <div class="tools">
                    **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                    
                    <div>
                      <embed id="ZeroClipboardMovie_15" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_15">
                      </embed>
                    </div>
                  </div>
                </div>
                
                
                  - <span class="preprocessor">#include <jni.h></span>
                  
                  - 
                  - <span class="comment">/*</span>
                  
                  - <span class="comment"> * 方法名称规定 : Java_完整包名类名_方法名()</span>
                  
                  - <span class="comment"> * JNIEnv 指针</span>
                  
                  - <span class="comment"> *</span>
                  
                  - <span class="comment"> * 参数介绍 :</span>
                  
                  - <span class="comment"> * env : 代表Java环境, 通过这个环境可以调用Java中的方法</span>
                  
                  - <span class="comment"> * thiz : 代表调用JNI方法的对象, 即MainActivity对象</span>
                  
                  - <span class="comment"> */</span>
                  
                  - jstring Java_shuliang_han_ndkhelloworld_MainActivity_helloFromJNI(JNIEnv *env, jobject thiz)
                  
                  - {
                  
                  - <span class="comment">/*</span>
                  
                  - <span class="comment">     * 调用 android-ndk-r9c\platforms\android-8\arch-arm\usr\include 中jni.h中的方法</span>
                  
                  - <span class="comment">     * jni.h 中定义的方法  jstring (*NewStringUTF)(JNIEnv*, const char*);</span>
                  
                  - <span class="comment">     */</span>
                  
                  - <span class="keyword">return</span> (*env)->NewStringUTF(env, <span class="string">&#8220;hello world jni 中文&#8221;</span>);
                  
                  - }
                  
                
              </div>
              
              

                **使用NDK重新编译hello.c文件** : 修改了C源码之后, 重新将该c文件编译成so文件;</div> 
                
                <div>
                  &#8212; **编译过程**: 打开cygwin, 进入cygdrive/ 下对应windows中源码项目中的jni目录, 执行 /android-ndk-r9c/ndk-build 命令;
                </div>
                
                <div>
                  ![](http://img.blog.csdn.net/20140131223258359)
                </div>
                
                <div>
                </div>
                
                <div>
                </div>
                
                <div>
                  **运行Android代码报错** : 因为jni中c文件有中文, 中文不能被识别;
                </div>
                
                <div>
                  <div class="dp-highlighter bg_java">
                    <div class="bar">
                      <div class="tools">
                        **[java]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                        
                        <div>
                          <embed id="ZeroClipboardMovie_16" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_16">
                          </embed>
                        </div>
                      </div>
                    </div>
                    
                    
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.803</span>: W/dalvikvm(<span class="number">389</span>): JNI WARNING: illegal continuation <span class="keyword">byte</span> <span class="number">0xd0</span>
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.803</span>: W/dalvikvm(<span class="number">389</span>):              string: <span class="string">&#8216;hello world jni ????&#8217;</span>
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.803</span>: W/dalvikvm(<span class="number">389</span>):              in Lshuliang/han/ndkhelloworld/MainActivity;.helloFromJNI ()Ljava/lang/String; (NewStringUTF)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.834</span>: I/dalvikvm(<span class="number">389</span>): <span class="string">&#8220;main&#8221;</span> prio=<span class="number">5</span> tid=<span class="number">1</span> NATIVE
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.834</span>: I/dalvikvm(<span class="number">389</span>):   | group=<span class="string">&#8220;main&#8221;</span> sCount=<span class="number"></span> dsCount=<span class="number"></span> obj=<span class="number">0x4001f1a8</span> self=<span class="number">0xce48</span>
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.834</span>: I/dalvikvm(<span class="number">389</span>):   | sysTid=<span class="number">389</span> nice=<span class="number"></span> sched=<span class="number"></span>/<span class="number"></span> cgrp=<span class="keyword">default</span> handle=-<span class="number">1345006528</span>
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.844</span>: I/dalvikvm(<span class="number">389</span>):   | schedstat=( <span class="number">257006717</span> <span class="number">305462830</span> <span class="number">51</span> )
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.844</span>: I/dalvikvm(<span class="number">389</span>):   at shuliang.han.ndkhelloworld.MainActivity.helloFromJNI(Native Method)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.844</span>: I/dalvikvm(<span class="number">389</span>):   at shuliang.han.ndkhelloworld.MainActivity.onCreate(MainActivity.java:<span class="number">26</span>)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.844</span>: I/dalvikvm(<span class="number">389</span>):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:<span class="number">1047</span>)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.853</span>: I/dalvikvm(<span class="number">389</span>):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:<span class="number">1611</span>)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.853</span>: I/dalvikvm(<span class="number">389</span>):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:<span class="number">1663</span>)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.853</span>: I/dalvikvm(<span class="number">389</span>):   at android.app.ActivityThread.access$<span class="number">1500</span>(ActivityThread.java:<span class="number">117</span>)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.864</span>: I/dalvikvm(<span class="number">389</span>):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:<span class="number">931</span>)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.864</span>: I/dalvikvm(<span class="number">389</span>):   at android.os.Handler.dispatchMessage(Handler.java:<span class="number">99</span>)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.864</span>: I/dalvikvm(<span class="number">389</span>):   at android.os.Looper.loop(Looper.java:<span class="number">123</span>)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.864</span>: I/dalvikvm(<span class="number">389</span>):   at android.app.ActivityThread.main(ActivityThread.java:<span class="number">3683</span>)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.864</span>: I/dalvikvm(<span class="number">389</span>):   at java.lang.reflect.Method.invokeNative(Native Method)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.874</span>: I/dalvikvm(<span class="number">389</span>):   at java.lang.reflect.Method.invoke(Method.java:<span class="number">507</span>)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.874</span>: I/dalvikvm(<span class="number">389</span>):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:<span class="number">839</span>)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.874</span>: I/dalvikvm(<span class="number">389</span>):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:<span class="number">597</span>)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.874</span>: I/dalvikvm(<span class="number">389</span>):   at dalvik.system.NativeStart.main(Native Method)
                      
                      - <span class="number">01</span>&#8211;<span class="number">31</span> <span class="number">14</span>:<span class="number">36</span>:<span class="number">04.884</span>: E/dalvikvm(<span class="number">389</span>): VM aborting
                      
                    
                  </div>
                </div>
                
                <div>
                  .
                </div>
                
                <div>
                </div>
                
                <div>
                </div>
                
                ## <a name="t33"></a>4. JNIEnv 详解
                
                <div>
                </div>
                
                <div>
                  **JNIEnv作用** : JNIEnv 是一个指针,**指向了一组JNI函数**, 这些函数可以在jni.h中查询到,**通过这些函数可以实现 Java层 与 JNI层的交互** , 通过JNIEnv 调用JNI函数 可以访问java虚拟机, 操作java对象;
                </div>
                
                <div>
                </div>
                
                <div>
                  **JNI线程相关性** : JNIEnv只在当前的线程有效,**JNIEnv不能跨线程传递**, 相同的Java线程调用本地方法, 所使用的JNIEnv是相同的, 一个Native方法不能被不同的Java线程调用;
                </div>
                
                <div>
                </div>
                
                <div>
                  **JNIEnv结构体系** : JNIEnv指针**指向一个线程相关的结构**,**线程相关结构指向一个指针数组**,**指针数组中的每个元素最终指向一个JNI函数**.
                </div>
                
                <div>
                </div>
                
                ### <a name="t34"></a>(1) JNIEnv的C/C++声明
                
                <div>
                </div>
                
                <div>
                  **jni.h中声明JNIEnv** : C语言中定义的JNIEnv 是 JNINativeInterface* , C++中定义的JNIEnv 是 _JNIEnv;
                </div>
                
                <div>
                  <div class="dp-highlighter bg_cpp">
                    <div class="bar">
                      <div class="tools">
                        **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                        
                        <div>
                          <embed id="ZeroClipboardMovie_17" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_17">
                          </embed>
                        </div>
                      </div>
                    </div>
                    
                    
                      - <span class="keyword">struct</span> _JNIEnv;
                      
                      - <span class="keyword">struct</span> _JavaVM;
                      
                      - <span class="keyword">typedef</span> <span class="keyword">const</span> <span class="keyword">struct</span> JNINativeInterface* C_JNIEnv;
                      
                      - 
                      - <span class="preprocessor">#if defined(__cplusplus)    //为了兼容C 和 C++两种代码 使用该 宏加以区分</span>
                      
                      - <span class="keyword">typedef</span> _JNIEnv JNIEnv;     <span class="comment">//C++ 中的JNIEnv类型</span>
                      
                      - <span class="keyword">typedef</span> _JavaVM JavaVM;
                      
                      - <span class="preprocessor">#else</span>
                      
                      - <span class="keyword">typedef</span> <span class="keyword">const</span> <span class="keyword">struct</span> JNINativeInterface* JNIEnv;<span class="comment">//C语言中的JNIEnv类型</span>
                      
                      - <span class="keyword">typedef</span> <span class="keyword">const</span> <span class="keyword">struct</span> JNIInvokeInterface* JavaVM;
                      
                      - <span class="preprocessor">#endif</span>
                      
                    
                  </div>
                  
                  ### <a name="t35"></a>(2) C语言中的JNIEnv
                </div>
                
                <div>
                </div>
                
                <div>
                  **关于JNIEnv指针调用解析** : C中**JNIEnv就是 const struct JNINativeInterface***, JNIEnv * env**等价于 JNINativeInterface** env**, 因此要得到JNINativeInterface结构体中定义的函数指针, 就必须先获取到 JNINativeInterface的一级指针对象 即 *env , 该**一级指针对象就是 JNINativeInterface* env**, 然后通过该**一级指针对象调用JNI函数 : (*env)->NewStringUTF(env, &#8220;hello&#8221;)**;
                </div>
                
                <div>
                </div>
                
                <div>
                  **在JNINativeInterface结构体中定义了一系列的关于Java操作的相关方法** :
                </div>
                
                <div>
                  <div class="dp-highlighter bg_cpp">
                    <div class="bar">
                      <div class="tools">
                        **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                        
                        <div>
                          <embed id="ZeroClipboardMovie_18" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_18">
                          </embed>
                        </div>
                      </div>
                    </div>
                    
                    
                      - <span class="comment">/*</span>
                      
                      - <span class="comment"> * Table of interface function pointers.</span>
                      
                      - <span class="comment"> */</span>
                      
                      - <span class="keyword">struct</span> JNINativeInterface {
                      
                      - <span class="keyword">void</span>*       reserved0;
                      
                      - <span class="keyword">void</span>*       reserved1;
                      
                      - 
                      - &#8230; &#8230;
                      
                      - 
                      - jboolean    (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID,
                      
                      - <span class="datatypes">va_list</span>);
                      
                      - jboolean    (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID,
                      
                      - jvalue*);
                      
                      - jbyte       (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, &#8230;);
                      
                      - jbyte       (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, <span class="datatypes">va_list</span>);
                      
                      - 
                      - &#8230; &#8230;
                      
                      - 
                      - <span class="keyword">void</span>*       (*GetDirectBufferAddress)(JNIEnv*, jobject);
                      
                      - jlong       (*GetDirectBufferCapacity)(JNIEnv*, jobject);
                      
                      - 
                      - <span class="comment">/* added in JNI 1.6 */</span>
                      
                      - jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject);
                      
                      - };
                      
                    
                  </div>
                  
                  ### <a name="t36"></a>(3) C++中的JNIEnv
                </div>
                
                <div>
                </div>
                
                <div>
                  **C++ 中的JNIEnv**: C++ 中的JNIEnv 就是 _JNIEnv 结构体, 二者是等同的; 因此在调用 JNI函数的时候, 只需要使用 env->NewStringUTF(env, &#8220;hello&#8221;)方法即可, 不用在进行*运算;
                </div>
                
                <div>
                </div>
                
                <div>
                  .
                </div>
                
                <div>
                  <div class="dp-highlighter bg_cpp">
                    <div class="bar">
                      <div class="tools">
                        **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                        
                        <div>
                          <embed id="ZeroClipboardMovie_19" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_19">
                          </embed>
                        </div>
                      </div>
                    </div>
                    
                    
                      - <span class="comment">/*</span>
                      
                      - <span class="comment"> * C++ object wrapper.</span>
                      
                      - <span class="comment"> *</span>
                      
                      - <span class="comment"> * This is usually overlaid on a C struct whose first element is a</span>
                      
                      - <span class="comment"> * JNINativeInterface*.  We rely somewhat on compiler behavior.</span>
                      
                      - <span class="comment"> */</span>
                      
                      - <span class="keyword">struct</span> _JNIEnv {
                      
                      - <span class="comment">/* do not rename this; it does not seem to be entirely opaque */</span>
                      
                      - <span class="keyword">const</span> <span class="keyword">struct</span> JNINativeInterface* functions;
                      
                      - 
                      - <span class="preprocessor">#if defined(__cplusplus)</span>
                      
                      - 
                      - jint GetVersion()
                      
                      - { <span class="keyword">return</span> functions->GetVersion(<span class="keyword">this</span>); }
                      
                      - 
                      - jlong GetDirectBufferCapacity(jobject buf)
                      
                      - { <span class="keyword">return</span> functions->GetDirectBufferCapacity(<span class="keyword">this</span>, buf); }
                      
                      - 
                      - <span class="comment">/* added in JNI 1.6 */</span>
                      
                      - jobjectRefType GetObjectRefType(jobject obj)
                      
                      - { <span class="keyword">return</span> functions->GetObjectRefType(<span class="keyword">this</span>, obj); }
                      
                      - <span class="preprocessor">#endif /*__cplusplus*/</span>
                      
                      - };
                      
                    
                  </div>
                  
                  ## <a name="t37"></a>5. JNI方法命名规则(标准JNI规范)
                </div>
                
                <div>
                </div>
                
                <div>
                  **JNI实现的方法 与 Java中Native方法的映射关系** : 使用方法名进行映射, 可以使用 javah 工具进入 bin/classes 目录下执行命令, 即可生成头文件;
                </div>
                
                <div>
                </div>
                
                <div>
                  **JNI方法参数介绍**:
                </div>
                
                <div>
                  &#8212; **参数①** : 第一个参数是JNI接口指针 JNIEnv;
                </div>
                
                <div>
                  &#8212; **参数②** : 如果Native方法是非静态的, 那么第二个参数就是对Java对象的引用, 如果Native方法是静态的, 那么第二个参数就是对Java类的Class对象的引用;
                </div>
                
                <div>
                </div>
                
                <div>
                  **JNI方法名规范** : 返回值 + Java前缀 + 全路径类名 + 方法名 + 参数① JNIEnv + 参数② jobject + 其它参数;
                </div>
                
                <div>
                  &#8212; **注意分隔符** : Java前缀 与 类名 以及类名之间的包名 和 方法名之间 使用 &#8220;_&#8221; 进行分割;
                </div>
                
                <div>
                </div>
                
                <div>
                  **声明 非静态 方法**:
                </div>
                
                <div>
                  &#8212; **Native方法** : public int hello (String str, int i);
                </div>
                
                <div>
                  &#8212; **JNI方法**: jint Java_shuliang_han_Hello_hello(JNIEnv * env, jobject obj, jstring str, jint i);
                </div>
                
                <div>
                </div>
                
                <div>
                  **声明 静态 方法** :
                </div>
                
                <div>
                  &#8212; **Native方法** : public static int hello (String str, int i);
                </div>
                
                <div>
                  &#8212;**JNI方法** : jint Java_shuliang_han_Hello_hello(JNIEnv * env, jobject clazz, jstring str, jint i);
                </div>
                
                <div>
                </div>
                
                <div>
                  **两种规范** : 以上是Java的标准JNI规范, 在Android中还有一套自定义的规范, 该规范是Android应用框架层 和 框架层交互使用的JNI规范, 依靠方法注册 映射 Native方法 和 JNI方法;
                </div>
                
                <div>
                </div>
                
                ## <a name="t38"></a>6. JNI方法签名规则
                
                <div>
                </div>
                
                <div>
                  **JNI识别Java方法** : **JNI依靠函数名 和 方法签名 识别方法**, 函数名是不能唯一识别一个方法的, 因为方法可以重载, 类型签名代表了 参数 和 返回值;
                </div>
                
                <div>
                  &#8212; **签名规则** : (**参数1类型签名参数2类型签名参数3类型签名参数N类型签名**&#8230;)**返回值类型签名**, 注意参数列表中没有任何间隔;
                </div>
                
                <div>
                </div>
                
                <div>
                  **Java类型 与 类型签名对照表** : 注意 boolean 与 long 不是大写首字母, 分别是 Z 与 J,  类是L全限定类名, 数组是[元素类型签名;
                </div>
                
                <div>
                  &#8212; **类的签名规则** :**L + 全限定名 + ;**三部分, 全限定类名以 / 分割;
                </div>
                
                <div>
                  <table border="1" width="500" cellspacing="1" cellpadding="1">
                    <tr>
                      <td>
                        Java类型
                      </td>
                      
                      <td>
                        类型签名
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        boolean
                      </td>
                      
                      <td>
                        Z
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        byte
                      </td>
                      
                      <td>
                        B
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        char
                      </td>
                      
                      <td>
                        C
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        short
                      </td>
                      
                      <td>
                        S
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        int
                      </td>
                      
                      <td>
                        I
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        long
                      </td>
                      
                      <td>
                        J
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        float
                      </td>
                      
                      <td>
                        F
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        double
                      </td>
                      
                      <td>
                        D
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        类
                      </td>
                      
                      <td>
                        L全限定类名
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        数组
                      </td>
                      
                      <td>
                        [元素类型签名
                      </td>
                    </tr>
                  </table>
                </div>
                
                <div>
                </div>
                
                <div>
                  eg. long function(int n, String str, int[] arr);
                </div>
                
                <div>
                  **该方法的签名** :**(ILjava/lang/String;[I)J**
                </div>
                
                <div>
                  .
                </div>
                
                <div>
                </div>
                
                <div>
                  .
                </div>
                
                <div>
                </div>
                
                # <a name="t39"></a>四. Java调用JNI法与日志打印
                
                <div>
                </div>
                
                <div>
                </div>
                
                ## <a name="t40"></a>1. JNI数据类型
                
                <div>
                </div>
                
                <div>
                </div>
                
                <div>
                  **Java数据类型 C数据类型 JNI数据类型对比** : 32位 与 64位机器可能会有出入;
                </div>
                
                <div>
                </div>
                
                <div>
                  <table border="1" width="600" cellspacing="1" cellpadding="1">
                    <tr>
                      <td>
                        **Java数据类型**
                      </td>
                      
                      <td>
                        **C本地类型**
                      </td>
                      
                      <td>
                        **JNI定义别名**
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        int
                      </td>
                      
                      <td>
                        long
                      </td>
                      
                      <td>
                        jint/jsize
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        long
                      </td>
                      
                      <td>
                        __int64
                      </td>
                      
                      <td>
                        jlong
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        byte
                      </td>
                      
                      <td>
                        signed char
                      </td>
                      
                      <td>
                        jbyte
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        boolean
                      </td>
                      
                      <td>
                        unsigned char
                      </td>
                      
                      <td>
                        jboolean
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        char
                      </td>
                      
                      <td>
                        unsigned short
                      </td>
                      
                      <td>
                        jchar
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        short
                      </td>
                      
                      <td>
                        short
                      </td>
                      
                      <td>
                        jshort
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        float
                      </td>
                      
                      <td>
                        float
                      </td>
                      
                      <td>
                        jfloat
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        double
                      </td>
                      
                      <td>
                        doyble
                      </td>
                      
                      <td>
                        jdouble
                      </td>
                    </tr>
                    
                    <tr>
                      <td>
                        object&#8217;
                      </td>
                      
                      <td>
                        _jobject
                      </td>
                      
                      <td>
                        jobject
                      </td>
                    </tr>
                  </table>
                </div>
                
                <div>
                  **数据类型表示方法** : int数组类型 jintArray , boolean数组 jbooleanArray &#8230;
                </div>
                
                <div>
                </div>
                
                <div>
                  **头文件定义类型** : 这些基本的数据类型在**jni.h 中都有相应的定义** :
                </div>
                
                <div>
                  <div class="dp-highlighter bg_cpp">
                    <div class="bar">
                      <div class="tools">
                        **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                        
                        <div>
                          <embed id="ZeroClipboardMovie_20" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_20">
                          </embed>
                        </div>
                      </div>
                    </div>
                    
                    
                      - jobject     (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
                      
                      - jboolean    (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, &#8230;);
                      
                      - jboolean    (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, <span class="datatypes">va_list</span>);
                      
                      - jboolean    (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
                      
                      - jbyte       (*CallByteMethod)(JNIEnv*, jobject, jmethodID, &#8230;);
                      
                      - jbyte       (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, <span class="datatypes">va_list</span>);
                      
                      - jbyte       (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
                      
                      - jchar       (*CallCharMethod)(JNIEnv*, jobject, jmethodID, &#8230;);
                      
                      - jchar       (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, <span class="datatypes">va_list</span>);
                      
                      - jchar       (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
                      
                      - jshort      (*CallShortMethod)(JNIEnv*, jobject, jmethodID, &#8230;);
                      
                      - jshort      (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, <span class="datatypes">va_list</span>);
                      
                      - jshort      (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
                      
                      - jint        (*CallIntMethod)(JNIEnv*, jobject, jmethodID, &#8230;);
                      
                      - jint        (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, <span class="datatypes">va_list</span>);
                      
                      - jint        (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
                      
                      - jlong       (*CallLongMethod)(JNIEnv*, jobject, jmethodID, &#8230;);
                      
                      - jlong       (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, <span class="datatypes">va_list</span>);
                      
                      - jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);
                      
                      - jbyteArray    (*NewByteArray)(JNIEnv*, jsize);
                      
                      - jcharArray    (*NewCharArray)(JNIEnv*, jsize);
                      
                      - jshortArray   (*NewShortArray)(JNIEnv*, jsize);
                      
                      - jintArray     (*NewIntArray)(JNIEnv*, jsize);
                      
                      - jlongArray    (*NewLongArray)(JNIEnv*, jsize);
                      
                      - jfloatArray   (*NewFloatArray)(JNIEnv*, jsize);
                      
                      - jdoubleArray  (*NewDoubleArray)(JNIEnv*, jsize);
                      
                    
                  </div>
                </div>
                
                ## <a name="t41"></a>2. JNI在Java和C语言之间传递int类型
                
                <div>
                </div>
                
                <div>
                </div>
                
                <div>
                  **Java中定义的方法** :
                </div>
                
                <div>
                  <div class="dp-highlighter bg_java">
                    <div class="bar">
                      <div class="tools">
                        **[java]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                        
                        <div>
                          <embed id="ZeroClipboardMovie_21" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_21">
                          </embed>
                        </div>
                      </div>
                    </div>
                    
                    
                      - <span class="comment">//将Java中的两个int值 传给C语言, 进行相加后, 返回java语言 shuliang.han.ndkparameterpassing.DataProvider</span>
                      
                      - <span class="keyword">public</span> <span class="keyword">native</span> <span class="keyword">int</span> add(<span class="keyword">int</span> x, <span class="keyword">int</span> y);
                      
                    
                  </div>
                  
                  

                    **C语言中定义的方法** :</div> 
                    
                    <div>
                      <div class="dp-highlighter bg_cpp">
                        <div class="bar">
                          <div class="tools">
                            **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                            
                            <div>
                              <embed id="ZeroClipboardMovie_22" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_22">
                              </embed>
                            </div>
                          </div>
                        </div>
                        
                        
                          - <span class="preprocessor">#include <jni.h></span>
                          
                          - 
                          - <span class="comment">//方法签名, Java环境 和 调用native方法的类 必不可少, 后面的参数就是native方法的参数</span>
                          
                          - jint Java_shuliang_han_ndkparameterpassing_DataProvider_add(JNIEnv * env, jobject obj, jint x, jint y)
                          
                          - {
                          
                          - <span class="keyword">return</span> x + y;
                          
                          - }
                          
                        
                      </div>
                      
                      

                        **使用NDK工具变异该c类库** :</div> 
                        
                        <div>
                          在cygwin中进入cygdrive, 然后**进入windows中相应的目录**, 执行 **/android-ndk-r9c/ndk-build** 命令, 即可完成编译;
                        </div>
                        
                        <div>
                          ![](http://img.blog.csdn.net/20140206151254187)
                        </div>
                        
                        <div>
                        </div>
                        
                        <div>
                        </div>
                        
                        ## <a name="t42"></a>3. NDK中C代码使用LogCat
                        
                        <div>
                        </div>
                        
                        <div>
                        </div>
                        
                        ### <a name="t43"></a>(1) 引入头文件
                        
                        <div>
                        </div>
                        
                        <div>
                          **NDK中断点调试** : 断点调试在NDK中实现极其困难, 因此在这里我们一般都是打印日志;
                        </div>
                        
                        <div>
                        </div>
                        
                        <div>
                          **引入头文件** : 在C代码中引入下面的头文件;
                        </div>
                        
                        <div>
                          <div class="dp-highlighter bg_cpp">
                            <div class="bar">
                              <div class="tools">
                                **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                
                                <div>
                                  <embed id="ZeroClipboardMovie_23" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_23">
                                  </embed>
                                </div>
                              </div>
                            </div>
                            
                            
                              - <span class="preprocessor">#include <android/log.h></span>
                              
                              - <span class="preprocessor">#define LOG_TAG &#8220;System.out&#8221;</span>
                              
                              - <span class="preprocessor">#define LOGD(&#8230;) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)</span>
                              
                              - <span class="preprocessor">#define LOGI(&#8230;) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)</span>
                              
                            
                          </div>
                          
                          

                            **头文件介绍** : log.h 是关于调用 LogCat日志文件;</div> 
                            
                            <div>
                              &#8212; **log.h头文件路径** : android-ndk-r9c\platforms\android-9\arch-arm\usr\include\android\log.h;
                            </div>
                            
                            <div>
                              &#8212; **主要方法** :  __android_log_write, 下面有该方法的解析, 传入参数 日志等级 日志标签 日志内容;
                            </div>
                            
                            <div>
                              &#8212; **宏定义** : __android_log_write 方法太麻烦, 这里做出一个映射, LOGD(&#8230;) 输出debug级别的日志, LOGI(&#8230;) 输出Info级别的日志;
                            </div>
                            
                            <div>
                              &#8212;**LogCat日志级别** : verbose < debug < info < warn < error < assert;
                            </div>
                            
                            <div>
                            </div>
                            
                            <div>
                              **使用到的log.h文件内容解析** : __android_log_write 方法中的日志等级参数就使用 枚举中的内容
                            </div>
                            
                            <div>
                              <div class="dp-highlighter bg_cpp">
                                <div class="bar">
                                  <div class="tools">
                                    **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                    
                                    <div>
                                      <embed id="ZeroClipboardMovie_24" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_24">
                                      </embed>
                                    </div>
                                  </div>
                                </div>
                                
                                
                                  - <span class="comment">/*</span>
                                  
                                  - <span class="comment"> * Android log priority values, in ascending priority order. 日志等级</span>
                                  
                                  - <span class="comment"> */</span>
                                  
                                  - <span class="keyword">typedef</span> <span class="keyword">enum</span> android_LogPriority {
                                  
                                  - ANDROID_LOG_UNKNOWN = 0,
                                  
                                  - ANDROID_LOG_DEFAULT,    <span class="comment">/* only for SetMinPriority() */</span>
                                  
                                  - ANDROID_LOG_VERBOSE,
                                  
                                  - ANDROID_LOG_DEBUG,
                                  
                                  - ANDROID_LOG_INFO,
                                  
                                  - ANDROID_LOG_WARN,
                                  
                                  - ANDROID_LOG_ERROR,
                                  
                                  - ANDROID_LOG_FATAL,
                                  
                                  - ANDROID_LOG_SILENT,     <span class="comment">/* only for SetMinPriority(); must be last */</span>
                                  
                                  - } android_LogPriority;
                                  
                                  - 
                                  - <span class="comment">/*</span>
                                  
                                  - <span class="comment"> * Send a simple string to the log. 向LogCat中输出日志 </span>
                                  
                                  - <span class="comment">    参数介绍: 日志优先级 , 日志标签 , 日志内容</span>
                                  
                                  - <span class="comment"> */</span>
                                  
                                  - <span class="datatypes">int</span> __android_log_write(<span class="datatypes">int</span> prio, <span class="keyword">const</span> <span class="datatypes">char</span> *tag, <span class="keyword">const</span> <span class="datatypes">char</span> *text);
                                  
                                
                              </div>
                              
                              

                                **C语言中输入输出函数占位符介绍** :</div> 
                                
                                <div>
                                  <table border="1" width="200" cellspacing="1" cellpadding="1">
                                    <tr>
                                      <td>
                                        占位符
                                      </td>
                                      
                                      <td>
                                        数据类型
                                      </td>
                                    </tr>
                                    
                                    <tr>
                                      <td>
                                        %d
                                      </td>
                                      
                                      <td>
                                        int
                                      </td>
                                    </tr>
                                    
                                    <tr>
                                      <td>
                                        %ld
                                      </td>
                                      
                                      <td>
                                        long int
                                      </td>
                                    </tr>
                                    
                                    <tr>
                                      <td>
                                        %c
                                      </td>
                                      
                                      <td>
                                        char
                                      </td>
                                    </tr>
                                    
                                    <tr>
                                      <td>
                                        %f
                                      </td>
                                      
                                      <td>
                                        float
                                      </td>
                                    </tr>
                                    
                                    <tr>
                                      <td>
                                        &lf
                                      </td>
                                      
                                      <td>
                                        double
                                      </td>
                                    </tr>
                                    
                                    <tr>
                                      <td>
                                        %x
                                      </td>
                                      
                                      <td>
                                        十六进制
                                      </td>
                                    </tr>
                                    
                                    <tr>
                                      <td>
                                        %O
                                      </td>
                                      
                                      <td>
                                        八进制
                                      </td>
                                    </tr>
                                    
                                    <tr>
                                      <td>
                                        %s
                                      </td>
                                      
                                      <td>
                                        字符串
                                      </td>
                                    </tr>
                                  </table>
                                </div>
                                
                                <div>
                                  .
                                </div>
                                
                                <div>
                                  .
                                </div>
                                
                                <div>
                                </div>
                                
                                ### <a name="t44"></a>(2) Android.mk增加liblog.so动态库
                                
                                <div>
                                </div>
                                
                                <div>
                                  **在该make配置文件中, 增加一行** : LOCAL_LDLIBS += -llog , 该语句添加在 LOCAL_SRC_FILES 语句下面一行;
                                </div>
                                
                                <div>
                                </div>
                                
                                <div>
                                  **完整的Android.mk文件** :
                                </div>
                                
                                <div>
                                  <div class="dp-highlighter bg_plain">
                                    <div class="bar">
                                      <div class="tools">
                                        **[plain]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                        
                                        <div>
                                          <embed id="ZeroClipboardMovie_25" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_25">
                                          </embed>
                                        </div>
                                      </div>
                                    </div>
                                    
                                    
                                      - LOCAL_PATH := $(call my-dir)
                                      
                                      - 
                                      - include $(CLEAR_VARS)
                                      
                                      - 
                                      - LOCAL_MODULE    := DataProvider
                                      
                                      - LOCAL_SRC_FILES := DataProvider.c
                                      
                                      - #增加log函数对应的函数库 liblog.so  libthread_db.a
                                      
                                      - LOCAL_LDLIBS += -llog -lthread_db
                                      
                                      - include $(BUILD_SHARED_LIBRARY)
                                      
                                    
                                  </div>
                                </div>
                                
                                <div>
                                  **函数库位置** : android-ndk-r9c\platforms\android-9\arch-arm\usr\lib;
                                </div>
                                
                                <div>
                                  **函数库截图** : 从该目录下的 liglog.so可以看出, 存在该库;
                                </div>
                                
                                <div>
                                  ![](http://img.blog.csdn.net/20140206154355906)
                                </div>
                                
                                <div>
                                  **引入函数库方法** : 使用 LOCAL_LDLIBS += -l函数库名, 注意**函数库名不带lib前缀** 和**.so 后缀**, 同时可以添加多个库, 使用 -l库1 -l库2 -库3 ;
                                </div>
                                
                                <div>
                                </div>
                                
                                <div>
                                </div>
                                
                                ### <a name="t45"></a>(3) 编译执行
                                
                                <div>
                                </div>
                                
                                <div>
                                  **根据(1) 中的占位符, 编写打印日志代码**:
                                </div>
                                
                                <div>
                                  <div class="dp-highlighter bg_cpp">
                                    <div class="bar">
                                      <div class="tools">
                                        **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                        
                                        <div>
                                          <embed id="ZeroClipboardMovie_26" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_26">
                                          </embed>
                                        </div>
                                      </div>
                                    </div>
                                    
                                    
                                      - <span class="comment">//Java中的int对应的是C语言中的long类型, 对应JNI中的jint类型, C语言中</span>
                                      
                                      - LOGI(<span class="string">&#8220;JNI_日志 : x = %ld , y = %ld&#8221;</span> , x , y);
                                      
                                    
                                  </div>
                                  
                                  

                                    **最终的包含打印日志的完整代码** : 注意, 这里有一处可能错误, 如果是32位机器, int类型占位符使用 %d 即可;</div> 
                                    
                                    <div>
                                      <div class="dp-highlighter bg_cpp">
                                        <div class="bar">
                                          <div class="tools">
                                            **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                            
                                            <div>
                                              <embed id="ZeroClipboardMovie_27" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_27">
                                              </embed>
                                            </div>
                                          </div>
                                        </div>
                                        
                                        
                                          - <span class="preprocessor">#include <jni.h></span>
                                          
                                          - <span class="preprocessor">#include <android/log.h></span>
                                          
                                          - <span class="preprocessor">#define LOG_TAG &#8220;System.out&#8221;</span>
                                          
                                          - <span class="preprocessor">#define LOGD(&#8230;) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)</span>
                                          
                                          - <span class="preprocessor">#define LOGI(&#8230;) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)</span>
                                          
                                          - 
                                          - 
                                          - <span class="comment">//方法签名, Java环境 和 调用native方法的类 必不可少, 后面的参数就是native方法的参数</span>
                                          
                                          - jint Java_shuliang_han_ndkparameterpassing_DataProvider_add(JNIEnv * env, jobject obj, jint x, jint y)
                                          
                                          - {
                                          
                                          - <span class="comment">//Java中的int对应的是C语言中的long类型, 对应JNI中的jint类型, C语言中</span>
                                          
                                          - LOGI(<span class="string">&#8220;JNI_日志 : x = %ld , y = %ld&#8221;</span> , x , y);
                                          
                                          - <span class="keyword">return</span> x + y;
                                          
                                          - }
                                          
                                        
                                      </div>
                                      
                                      

                                        **重新编译C文件** : 执行 **/android-ndk-r9c/ndk-build**命令;</div> 
                                        
                                        <div>
                                          &#8212; **第一次编译** : 出现警告, long int占位符行不通, 注意区分机器位长, 64位 与 32位不同, 这样编译出现的结果就不会打印日志;
                                        </div>
                                        
                                        <div>
                                          ![](http://img.blog.csdn.net/20140206155158937)
                                        </div>
                                        
                                        <div>
                                          &#8212; **第二次编译** : 将占位符改为 %d ;
                                        </div>
                                        
                                        <div>
                                          ![](http://img.blog.csdn.net/20140206160147875)
                                        </div>
                                        
                                        <div>
                                        </div>
                                        
                                        <div>
                                          **执行按钮之后打印的日志** : 虽然有乱码, 不过显示出来了;
                                        </div>
                                        
                                        <div>
                                          ![](http://img.blog.csdn.net/20140206160218625)
                                        </div>
                                        
                                        <div>
                                        </div>
                                        
                                        <div>
                                          ![](http://img.blog.csdn.net/20140206184130671)
                                        </div>
                                        
                                        <div>
                                        </div>
                                        
                                        <div>
                                        </div>
                                        
                                        ## <a name="t46"></a>4. 字符串处理
                                        
                                        <div>
                                          .
                                        </div>
                                        
                                        <div>
                                        </div>
                                        
                                        <div>
                                          **Java中的String转为C语言中的char字符串** : 下面的工具方法可以在C程序中解决这个问题;
                                        </div>
                                        
                                        <div>
                                          <div class="dp-highlighter bg_cpp">
                                            <div class="bar">
                                              <div class="tools">
                                                **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                
                                                <div>
                                                  <embed id="ZeroClipboardMovie_28" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_28">
                                                  </embed>
                                                </div>
                                              </div>
                                            </div>
                                            
                                            
                                              - <span class="comment">// java中的jstring, 转化为c的一个字符数组</span>
                                              
                                              - <span class="datatypes">char</span>* Jstring2CStr(JNIEnv* env, jstring jstr) {
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//声明了一个字符串变量 rtn</span>
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="datatypes">char</span>* rtn = NULL;
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//找到Java中的String的Class对象</span>
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>jclass clsstring = (*env)->FindClass(env, <span class="string">&#8220;java/lang/String&#8221;</span>);
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//创建一个Java中的字符串 &#8220;GB2312&#8221;</span>
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>jstring strencode = (*env)->NewStringUTF(env, <span class="string">&#8220;GB2312&#8221;</span>);
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">/*</span>
                                              
                                              - <span class="comment"><span style=&#8221;white-space:pre&#8221;>  </span> * 获取String中定义的方法 getBytes(), 该方法的参数是 String类型的, 返回值是 byte[]数组</span>
                                              
                                              - <span class="comment"><span style=&#8221;white-space:pre&#8221;>  </span> * &#8220;(Ljava/lang/String;)[B&#8221; 方法前面解析 :</span>
                                              
                                              - <span class="comment"><span style=&#8221;white-space:pre&#8221;>  </span> * &#8212; Ljava/lang/String; 表示参数是String字符串</span>
                                              
                                              - <span class="comment"><span style=&#8221;white-space:pre&#8221;>  </span> * &#8212; [B : 中括号表示这是一个数组, B代表byte类型, 返回值是一个byte数组</span>
                                              
                                              - <span class="comment"><span style=&#8221;white-space:pre&#8221;>  </span> */</span>
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>jmethodID mid = (*env)->GetMethodID(env, clsstring, <span class="string">&#8220;getBytes&#8221;</span>,
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>          </span><span class="string">&#8220;(Ljava/lang/String;)[B&#8221;</span>);
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//调用Java中的getBytes方法, 传入参数介绍 参数②表示调用该方法的对象, 参数③表示方法id , 参数④表示方法参数</span>
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid,
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>          </span>strencode); <span class="comment">// String .getByte(&#8220;GB2312&#8221;);</span>
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//获取数组的长度</span>
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>jsize alen = (*env)->GetArrayLength(env, barr);
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//获取数组中的所有的元素 , 存放在 jbyte*数组中</span>
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//将Java数组中所有元素拷贝到C的char*数组中, 注意C语言数组结尾要加一个 &#8216;\0&#8217;</span>
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="keyword">if</span> (alen > 0) {
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>      </span>rtn = (<span class="datatypes">char</span>*) malloc(alen + 1); <span class="comment">//new   char[alen+1]; &#8220;\0&#8221;</span>
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>      </span>memcpy(rtn, ba, alen);
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>      </span>rtn[alen] = 0;
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>}
                                              
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>(*env)->ReleaseByteArrayElements(env, barr, ba, 0); <span class="comment">//释放内存</span>
                                              
                                              - 
                                              - 
                                              - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="keyword">return</span> rtn;
                                              
                                              - }
                                              
                                            
                                          </div>
                                          
                                          <div>
                                          </div>
                                          
                                          <div>
                                            **Jstring2CStr方法讲解** :
                                          </div>
                                          
                                          <div>
                                            a. **获取Java中String类型的class对象** : 参数 : 上下文环境 env, String类完整路径 ;
                                          </div>
                                          
                                          <div>
                                            <div class="dp-highlighter bg_cpp">
                                              <div class="bar">
                                                <div class="tools">
                                                  **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                  
                                                  <div>
                                                    <embed id="ZeroClipboardMovie_29" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_29">
                                                    </embed>
                                                  </div>
                                                </div>
                                              </div>
                                              
                                              
                                                - jclass clsstring = (*env)->FindClass(env, <span class="string">&#8220;java/lang/String&#8221;</span>);
                                                
                                              
                                            </div>
                                            
                                            

                                              b.**创建Java字符串** : 使用 NewStringUTF 方法;</div> 
                                              
                                              <div>
                                                <div class="dp-highlighter bg_cpp">
                                                  <div class="bar">
                                                    <div class="tools">
                                                      **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                      
                                                      <div>
                                                        <embed id="ZeroClipboardMovie_30" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_30">
                                                        </embed>
                                                      </div>
                                                    </div>
                                                  </div>
                                                  
                                                  
                                                    - jstring strencode = (*env)->NewStringUTF(env, <span class="string">&#8220;GB2312&#8221;</span>);
                                                    
                                                  
                                                </div>
                                                
                                                

                                                  c.**获取String中的getBytes()方法** : 参数介绍 ① env 上下文环境 ② 完整的类路径 ③ 方法名 ④ 方法签名, 方法签名 Ljava/lang/String; 代表参数是String字符串, [B  中括号表示这是一个数组, B代表byte类型, 返回值是一个byte数组;</div> 
                                                  
                                                  <div>
                                                    <div class="dp-highlighter bg_cpp">
                                                      <div class="bar">
                                                        <div class="tools">
                                                          **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                          
                                                          <div>
                                                            <embed id="ZeroClipboardMovie_31" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_31">
                                                            </embed>
                                                          </div>
                                                        </div>
                                                      </div>
                                                      
                                                      
                                                        - jmethodID mid = (*env)->GetMethodID(env, clsstring, <span class="string">&#8220;getBytes&#8221;</span>,
                                                        
                                                        - <span class="string">&#8220;(Ljava/lang/String;)[B&#8221;</span>);
                                                        
                                                      
                                                    </div>
                                                    
                                                    

                                                      d. **获取数组的长度** :</div> 
                                                      
                                                      <div>
                                                        <div class="dp-highlighter bg_cpp">
                                                          <div class="bar">
                                                            <div class="tools">
                                                              **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                              
                                                              <div>
                                                                <embed id="ZeroClipboardMovie_32" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_32">
                                                                </embed>
                                                              </div>
                                                            </div>
                                                          </div>
                                                          
                                                          
                                                            - jsize alen = (*env)->GetArrayLength(env, barr);
                                                            
                                                          
                                                        </div>
                                                        
                                                        

                                                          e. 获取数组元素 : 获取数组中的所有的元素 , 存放在 jbyte*数组中;
                                                        

                                                      </div>
                                                      
                                                      <div>
                                                        <div class="dp-highlighter bg_cpp">
                                                          <div class="bar">
                                                            <div class="tools">
                                                              **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                              
                                                              <div>
                                                                <embed id="ZeroClipboardMovie_33" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_33">
                                                                </embed>
                                                              </div>
                                                            </div>
                                                          </div>
                                                          
                                                          
                                                            - jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
                                                            
                                                          
                                                        </div>
                                                        
                                                        

                                                          f.**数组拷贝**: 将Java数组中所有元素拷贝到C的char*数组中, 注意C语言数组结尾要加一个 &#8216;\0&#8217;;</div> 
                                                          
                                                          <div>
                                                            <div class="dp-highlighter bg_cpp">
                                                              <div class="bar">
                                                                <div class="tools">
                                                                  **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                                  
                                                                  <div>
                                                                    <embed id="ZeroClipboardMovie_34" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_34">
                                                                    </embed>
                                                                  </div>
                                                                </div>
                                                              </div>
                                                              
                                                              
                                                                - <span class="keyword">if</span> (alen > 0) {
                                                                
                                                                - rtn = (<span class="datatypes">char</span>*) malloc(alen + 1); <span class="comment">//new   char[alen+1]; &#8220;\0&#8221;</span>
                                                                
                                                                - memcpy(rtn, ba, alen);
                                                                
                                                                - rtn[alen] = 0;
                                                                
                                                                - }
                                                                
                                                              
                                                            </div>
                                                            
                                                            

                                                              g.**释放内存** :</div> 
                                                              
                                                              <div>
                                                                <div class="dp-highlighter bg_cpp">
                                                                  <div class="bar">
                                                                    <div class="tools">
                                                                      **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                                      
                                                                      <div>
                                                                        <embed id="ZeroClipboardMovie_35" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_35">
                                                                        </embed>
                                                                      </div>
                                                                    </div>
                                                                  </div>
                                                                  
                                                                  
                                                                    - (*env)->ReleaseByteArrayElements(env, barr, ba, 0); <span class="comment">//释放内存</span>
                                                                    
                                                                  
                                                                </div>
                                                              </div>
                                                              
                                                              <div>
                                                              </div>
                                                              
                                                              <div>
                                                                

                                                                  .
                                                                

                                                                
                                                                

                                                                  **作者** : **万境绝尘 **
                                                                

                                                                
                                                                

                                                                  **转载请注明出处** : [**http://blog.csdn.net/shulianghan/article/details/18964835**](http://blog.csdn.net/shulianghan/article/details/18964835)
                                                                

                                                                
                                                                

                                                                  .
                                                                

                                                              </div>
                                                              
                                                              

                                                                **C语言方法** : 注意调用Jstring2CStr方法之后要强转, 否则会出错, Jstring2CStr方法要定义在该方法的前面, C语言中的方法要先声明才能使用;</div> 
                                                                
                                                                <div>
                                                                  <div class="dp-highlighter bg_cpp">
                                                                    <div class="bar">
                                                                      <div class="tools">
                                                                        **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                                        
                                                                        <div>
                                                                          <embed id="ZeroClipboardMovie_36" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_36">
                                                                          </embed>
                                                                        </div>
                                                                      </div>
                                                                    </div>
                                                                    
                                                                    
                                                                      - jstring Java_shuliang_han_ndkparameterpassing_DataProvider_sayHelloInc(JNIEnv *env, jobject obj, jstring str)
                                                                      
                                                                      - {
                                                                      
                                                                      - <span class="datatypes">char</span> *p = (<span class="datatypes">char</span>*)Jstring2CStr(env, str);
                                                                      
                                                                      - <span class="comment">//打印Java传递过来的数据  </span>
                                                                      
                                                                      - LOGI(<span class="string">&#8220;Java JNI string parameter is : %s&#8221;</span>, p);
                                                                      
                                                                      - 
                                                                      - <span class="datatypes">char</span> *append = <span class="string">&#8220;append&#8221;</span>;
                                                                      
                                                                      - 
                                                                      - <span class="comment">//strcat(dest, source) 函数可以将source字符串 添加到dest字符串后面  </span>
                                                                      
                                                                      - <span class="keyword">return</span> (*env)->NewStringUTF(env, strcat(p, append));
                                                                      
                                                                      - }
                                                                      
                                                                    
                                                                  </div>
                                                                  
                                                                  

                                                                    &#8212; **如果没有强转会出现下面的错误** : char *p = Jstring2CStr(env, str);

                                                                    &#8212; **将Jstring2CStr方法定义在主方法下面会出现下面错误** :</div> 
                                                                    
                                                                    <div>
                                                                    </div>
                                                                    
                                                                    <div>
                                                                      ![](http://img.blog.csdn.net/20140206183825406)
                                                                    </div>
                                                                    
                                                                    <div>
                                                                      **Java源码** :
                                                                    </div>
                                                                    
                                                                    <div>
                                                                      <div class="dp-highlighter bg_java">
                                                                        <div class="bar">
                                                                          <div class="tools">
                                                                            **[java]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                                            
                                                                            <div>
                                                                              <embed id="ZeroClipboardMovie_37" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_37">
                                                                              </embed>
                                                                            </div>
                                                                          </div>
                                                                        </div>
                                                                        
                                                                        
                                                                          - <span class="keyword">case</span> R.id.sayHelloInc:
                                                                          
                                                                          - Toast.makeText(getApplicationContext(), dataProvider.sayHelloInc(<span class="string">&#8220;Hello&#8221;</span>), Toast.LENGTH_LONG).show();
                                                                          
                                                                          - <span class="keyword">break</span>;
                                                                          
                                                                        
                                                                      </div>
                                                                      
                                                                      

                                                                        **编译之后运行结果** :</div> 
                                                                        
                                                                        <div>
                                                                        </div>
                                                                        
                                                                        <div>
                                                                          ![](http://img.blog.csdn.net/20140206184007406)
                                                                        </div>
                                                                        
                                                                        <div>
                                                                        </div>
                                                                        
                                                                        <div>
                                                                          ![](http://img.blog.csdn.net/20140206184042125)
                                                                        </div>
                                                                        
                                                                        <div>
                                                                        </div>
                                                                        
                                                                        ## <a name="t47"></a>5. 开发JNI程序流程
                                                                        
                                                                        <div>
                                                                        </div>
                                                                        
                                                                        <div>
                                                                          a. **C语言类库接口** : 存在C语言类库, 调用接口为login_server(char* address, char* username, char* password);

b. Java定义本地方法 : public native void LoginServer(String address, String user, String pwd);

                                                                        <div>
                                                                          c. **C语言JNI代码** : Java_包名_类名_LoginServer(JNIEnv* env, jobject obj, jstring address, jstring user, jstring pwd){&#8230;调C接口};

                                                                          
                                                                          

                                                                            **注意跨语言字符串转换**: JNI方法中, 要将Java的String字符串转为C中的char*字符串;
                                                                          

                                                                          
                                                                          

                                                                            **首先验证C码农提供的代码是否可用** : 验证该api是否可用, 在一个 int main() 函数中进行测试, 根据该测试代码查看方法执行相关的情况;</div> 
                                                                            
                                                                            <div>
                                                                            </div>
                                                                            
                                                                            ## <a name="t48"></a>6. 数组参数处理
                                                                            
                                                                            <div>
                                                                            </div>
                                                                            
                                                                            <div>
                                                                              **模块讲解** : 在该模块中, Java语言传递一个int数组参数给C语言, C语言将这一组参数读取出来, 并且输出到Android的LogCat中, 这里涉及到了两个重要的JNI方法, 一个数**获取数组长度方法**, 一个是**获取数组中每个元素的方法**;

                                                                              
                                                                              

                                                                                **获取数组长度方法** : jni中定义 &#8211; jsize (*GetArrayLength)(JNIEnv*, jarray);

创建数组相关方法 :

                                                                                <div>
                                                                                  <div class="dp-highlighter bg_cpp">
                                                                                    <div class="bar">
                                                                                      <div class="tools">
                                                                                        **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                                                        
                                                                                        <div>
                                                                                          <embed id="ZeroClipboardMovie_38" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_38">
                                                                                          </embed>
                                                                                        </div>
                                                                                      </div>
                                                                                    </div>
                                                                                    
                                                                                    
                                                                                      - jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);
                                                                                      
                                                                                      - jbyteArray    (*NewByteArray)(JNIEnv*, jsize);
                                                                                      
                                                                                      - jcharArray    (*NewCharArray)(JNIEnv*, jsize);
                                                                                      
                                                                                      - jshortArray   (*NewShortArray)(JNIEnv*, jsize);
                                                                                      
                                                                                      - jintArray     (*NewIntArray)(JNIEnv*, jsize);
                                                                                      
                                                                                      - jlongArray    (*NewLongArray)(JNIEnv*, jsize);
                                                                                      
                                                                                      - jfloatArray   (*NewFloatArray)(JNIEnv*, jsize);
                                                                                      
                                                                                      - jdoubleArray  (*NewDoubleArray)(JNIEnv*, jsize);
                                                                                      
                                                                                    
                                                                                  </div>
                                                                                  
                                                                                  

                                                                                    **获取数组元素相关方法** :</div> 
                                                                                    
                                                                                    <div>
                                                                                      <div class="dp-highlighter bg_cpp">
                                                                                        <div class="bar">
                                                                                          <div class="tools">
                                                                                            **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                                                            
                                                                                            <div>
                                                                                              <embed id="ZeroClipboardMovie_39" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_39">
                                                                                              </embed>
                                                                                            </div>
                                                                                          </div>
                                                                                        </div>
                                                                                        
                                                                                        
                                                                                          - jboolean*   (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*);
                                                                                          
                                                                                          - jbyte*      (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*);
                                                                                          
                                                                                          - jchar*      (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*);
                                                                                          
                                                                                          - jshort*     (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*);
                                                                                          
                                                                                          - jint*       (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
                                                                                          
                                                                                          - jlong*      (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*);
                                                                                          
                                                                                          - jfloat*     (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*);
                                                                                          
                                                                                          - jdouble*    (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*);
                                                                                          
                                                                                        
                                                                                      </div>
                                                                                      
                                                                                      

                                                                                        **C语言代码** :</div> 
                                                                                        
                                                                                        <div>
                                                                                          <div class="dp-highlighter bg_cpp">
                                                                                            <div class="bar">
                                                                                              <div class="tools">
                                                                                                **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                                                                
                                                                                                <div>
                                                                                                  <embed id="ZeroClipboardMovie_40" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_40">
                                                                                                  </embed>
                                                                                                </div>
                                                                                              </div>
                                                                                            </div>
                                                                                            
                                                                                            
                                                                                              - jintArray Java_shuliang_han_ndkparameterpassing_DataProvider_intMethod(JNIEnv *env, jobject obj, jintArray arr)
                                                                                              
                                                                                              - {
                                                                                              
                                                                                              - <span class="comment">//获取arr大小  </span>
                                                                                              
                                                                                              - <span class="datatypes">int</span> len = (*env)->GetArrayLength(env, arr);
                                                                                              
                                                                                              - 
                                                                                              - <span class="comment">//在LogCat中打印出arr的大小  </span>
                                                                                              
                                                                                              - LOGI(<span class="string">&#8220;the length of array is %d&#8221;</span>, len);
                                                                                              
                                                                                              - 
                                                                                              - <span class="comment">//如果长度为0, 返回arr  </span>
                                                                                              
                                                                                              - <span class="keyword">if</span>(len == 0)
                                                                                              
                                                                                              - <span class="keyword">return</span> arr;
                                                                                              
                                                                                              - 
                                                                                              - <span class="comment">//如果长度大于0, 那么获取数组中的每个元素  </span>
                                                                                              
                                                                                              - jint* p = (*env)->GetIntArrayElements(env, arr, 0);
                                                                                              
                                                                                              - 
                                                                                              - <span class="comment">//打印出数组中每个元素的值  </span>
                                                                                              
                                                                                              - <span class="datatypes">int</span> i = 0;
                                                                                              
                                                                                              - <span class="keyword">for</span>(; i < len; i ++)
                                                                                              
                                                                                              - {
                                                                                              
                                                                                              - LOGI(<span class="string">&#8220;arr[%d] = %d&#8221;</span>, i, *(p + i));
                                                                                              
                                                                                              - }
                                                                                              
                                                                                              - 
                                                                                              - <span class="keyword">return</span> arr;
                                                                                              
                                                                                              - 
                                                                                              - }
                                                                                              
                                                                                            
                                                                                          </div>
                                                                                        </div>
                                                                                        
                                                                                        <div>
                                                                                          **Java代码** :
                                                                                        </div>
                                                                                        
                                                                                        <div>
                                                                                          <div class="dp-highlighter bg_java">
                                                                                            <div class="bar">
                                                                                              <div class="tools">
                                                                                                **[java]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                                                                
                                                                                                <div>
                                                                                                  <embed id="ZeroClipboardMovie_41" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_41">
                                                                                                  </embed>
                                                                                                </div>
                                                                                              </div>
                                                                                            </div>
                                                                                            
                                                                                            
                                                                                              - <span class="keyword">case</span> R.id.intMethod:
                                                                                              
                                                                                              - <span class="keyword">int</span>[] array = {<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>};
                                                                                              
                                                                                              - dataProvider.intMethod(array);
                                                                                              
                                                                                              - <span class="keyword">break</span>;
                                                                                              
                                                                                            
                                                                                          </div>
                                                                                          
                                                                                          

                                                                                            **执行结果** : 上面的那种LogCat竟然启动失败, 只能将就着用这个了;</div> 
                                                                                            
                                                                                            <div>
                                                                                              ![](http://img.blog.csdn.net/20140207144250609)
                                                                                            </div>
                                                                                            
                                                                                            <div>
                                                                                            </div>
                                                                                            
                                                                                            ## <a name="t49"></a>7. 本程序源码
                                                                                            
                                                                                            <div>
                                                                                            </div>
                                                                                            
                                                                                            <div>
                                                                                              **XML布局文件** :
                                                                                            </div>
                                                                                            
                                                                                            <div>
                                                                                              <div class="dp-highlighter bg_html">
                                                                                                <div class="bar">
                                                                                                  <div class="tools">
                                                                                                    **[html]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                                                                    
                                                                                                    <div>
                                                                                                      <embed id="ZeroClipboardMovie_42" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_42">
                                                                                                      </embed>
                                                                                                    </div>
                                                                                                  </div>
                                                                                                </div>
                                                                                                
                                                                                                
                                                                                                  - <span class="tag"><</span><span class="tag-name">LinearLayout</span> <span class="attribute">xmlns:android</span>=<span class="attribute-value">&#8220;http://schemas.android.com/apk/res/android&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">xmlns:tools</span>=<span class="attribute-value">&#8220;http://schemas.android.com/tools&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:orientation</span>=<span class="attribute-value">&#8220;vertical&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;match_parent&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;match_parent&#8221;</span> <span class="tag">></span>
                                                                                                  
                                                                                                  - 
                                                                                                  - <span class="tag"><</span><span class="tag-name">Button</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:id</span>=<span class="attribute-value">&#8220;@+id/add&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:text</span>=<span class="attribute-value">&#8220;调用 add 本地 方法&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:onClick</span>=<span class="attribute-value">&#8220;onClick&#8221;</span><span class="tag">/></span>
                                                                                                  
                                                                                                  - 
                                                                                                  - <span class="tag"><</span><span class="tag-name">Button</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:id</span>=<span class="attribute-value">&#8220;@+id/sayHelloInc&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:text</span>=<span class="attribute-value">&#8220;调用 sayHelloInc 本地 方法&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:onClick</span>=<span class="attribute-value">&#8220;onClick&#8221;</span><span class="tag">/></span>
                                                                                                  
                                                                                                  - 
                                                                                                  - <span class="tag"><</span><span class="tag-name">Button</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:id</span>=<span class="attribute-value">&#8220;@+id/intMethod&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:layout_width</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:layout_height</span>=<span class="attribute-value">&#8220;wrap_content&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:text</span>=<span class="attribute-value">&#8220;调用 intMethod 本地 方法&#8221;</span>
                                                                                                  
                                                                                                  - <span class="attribute">android:onClick</span>=<span class="attribute-value">&#8220;onClick&#8221;</span><span class="tag">/></span>
                                                                                                  
                                                                                                  - 
                                                                                                  - <span class="tag"></</span><span class="tag-name">LinearLayout</span><span class="tag">></span>
                                                                                                  
                                                                                                
                                                                                              </div>
                                                                                              
                                                                                              

                                                                                                **Java源码** :</div> 
                                                                                                
                                                                                                <div>
                                                                                                  &#8212; **MainActivity源码** :
                                                                                                </div>
                                                                                                
                                                                                                <div>
                                                                                                  <div class="dp-highlighter bg_java">
                                                                                                    <div class="bar">
                                                                                                      <div class="tools">
                                                                                                        **[java]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                                                                        
                                                                                                        <div>
                                                                                                          <embed id="ZeroClipboardMovie_43" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_43">
                                                                                                          </embed>
                                                                                                        </div>
                                                                                                      </div>
                                                                                                    </div>
                                                                                                    
                                                                                                    
                                                                                                      - <span class="keyword">package</span> shuliang.han.ndkparameterpassing;
                                                                                                      
                                                                                                      - 
                                                                                                      - <span class="keyword">import</span> android.app.Activity;
                                                                                                      
                                                                                                      - <span class="keyword">import</span> android.os.Bundle;
                                                                                                      
                                                                                                      - <span class="keyword">import</span> android.view.View;
                                                                                                      
                                                                                                      - <span class="keyword">import</span> android.widget.Toast;
                                                                                                      
                                                                                                      - 
                                                                                                      - <span class="keyword">public</span> <span class="keyword">class</span> MainActivity <span class="keyword">extends</span> Activity {
                                                                                                      
                                                                                                      - 
                                                                                                      - <span class="keyword">static</span>{
                                                                                                      
                                                                                                      - System.loadLibrary(<span class="string">&#8220;DataProvider&#8221;</span>);
                                                                                                      
                                                                                                      - }
                                                                                                      
                                                                                                      - 
                                                                                                      - DataProvider dataProvider;
                                                                                                      
                                                                                                      - <span class="annotation">@Override</span>
                                                                                                      
                                                                                                      - <span class="keyword">public</span> <span class="keyword">void</span> onCreate(Bundle savedInstanceState) {
                                                                                                      
                                                                                                      - <span class="keyword">super</span>.onCreate(savedInstanceState);
                                                                                                      
                                                                                                      - setContentView(R.layout.activity_main);
                                                                                                      
                                                                                                      - dataProvider = <span class="keyword">new</span> DataProvider();
                                                                                                      
                                                                                                      - }
                                                                                                      
                                                                                                      - 
                                                                                                      - <span class="keyword">public</span> <span class="keyword">void</span> onClick(View view) {
                                                                                                      
                                                                                                      - 
                                                                                                      - <span class="keyword">int</span> id = view.getId();
                                                                                                      
                                                                                                      - 
                                                                                                      - <span class="keyword">switch</span> (id) {
                                                                                                      
                                                                                                      - <span class="keyword">case</span> R.id.add:
                                                                                                      
                                                                                                      - <span class="keyword">int</span> result = dataProvider.add(<span class="number">1</span>, <span class="number">2</span>);
                                                                                                      
                                                                                                      - Toast.makeText(getApplicationContext(), <span class="string">&#8220;the add result : &#8220;</span> + result, Toast.LENGTH_LONG).show();
                                                                                                      
                                                                                                      - <span class="keyword">break</span>;
                                                                                                      
                                                                                                      - 
                                                                                                      - <span class="keyword">case</span> R.id.sayHelloInc:
                                                                                                      
                                                                                                      - Toast.makeText(getApplicationContext(), dataProvider.sayHelloInc(<span class="string">&#8220;Hello&#8221;</span>), Toast.LENGTH_LONG).show();
                                                                                                      
                                                                                                      - <span class="keyword">break</span>;
                                                                                                      
                                                                                                      - 
                                                                                                      - <span class="keyword">case</span> R.id.intMethod:
                                                                                                      
                                                                                                      - <span class="keyword">int</span>[] array = {<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>};
                                                                                                      
                                                                                                      - dataProvider.intMethod(array);
                                                                                                      
                                                                                                      - <span class="keyword">break</span>;
                                                                                                      
                                                                                                      - 
                                                                                                      - <span class="keyword">default</span>:
                                                                                                      
                                                                                                      - <span class="keyword">break</span>;
                                                                                                      
                                                                                                      - }
                                                                                                      
                                                                                                      - }
                                                                                                      
                                                                                                      - 
                                                                                                      - }
                                                                                                      
                                                                                                    
                                                                                                  </div>
                                                                                                  
                                                                                                  

                                                                                                    &#8212;**DataProvider源码** :</div> 
                                                                                                    
                                                                                                    <div>
                                                                                                      <div class="dp-highlighter bg_java">
                                                                                                        <div class="bar">
                                                                                                          <div class="tools">
                                                                                                            **[java]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                                                                            
                                                                                                            <div>
                                                                                                              <embed id="ZeroClipboardMovie_44" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_44">
                                                                                                              </embed>
                                                                                                            </div>
                                                                                                          </div>
                                                                                                        </div>
                                                                                                        
                                                                                                        
                                                                                                          - <span class="keyword">package</span> shuliang.han.ndkparameterpassing;
                                                                                                          
                                                                                                          - 
                                                                                                          - <span class="keyword">public</span> <span class="keyword">class</span> DataProvider {
                                                                                                          
                                                                                                          - 
                                                                                                          - <span class="comment">//将Java中的两个int值 传给C语言, 进行相加后, 返回java语言 shuliang.han.ndkparameterpassing.DataProvider</span>
                                                                                                          
                                                                                                          - <span class="keyword">public</span> <span class="keyword">native</span> <span class="keyword">int</span> add(<span class="keyword">int</span> x, <span class="keyword">int</span> y);
                                                                                                          
                                                                                                          - 
                                                                                                          - <span class="comment">//将Java字符串传递给C语言, C语言处理字符串之后, 将处理结果返回给java</span>
                                                                                                          
                                                                                                          - <span class="keyword">public</span> <span class="keyword">native</span> String sayHelloInc(String s);
                                                                                                          
                                                                                                          - 
                                                                                                          - <span class="comment">//将java中的int数组传递给C语言, C语言为每个元素加10, 返回给Java</span>
                                                                                                          
                                                                                                          - <span class="keyword">public</span> <span class="keyword">native</span> <span class="keyword">int</span>[] intMethod(<span class="keyword">int</span>[] nums);
                                                                                                          
                                                                                                          - 
                                                                                                          - }
                                                                                                          
                                                                                                        
                                                                                                      </div>
                                                                                                      
                                                                                                      

                                                                                                        **JNI相关源码** :</div> 
                                                                                                        
                                                                                                        <div>
                                                                                                          &#8212; **Android.mk源码** :
                                                                                                        </div>
                                                                                                        
                                                                                                        <div>
                                                                                                          <div class="dp-highlighter bg_plain">
                                                                                                            <div class="bar">
                                                                                                              <div class="tools">
                                                                                                                **[plain]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                                                                                
                                                                                                                <div>
                                                                                                                  <embed id="ZeroClipboardMovie_45" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_45">
                                                                                                                  </embed>
                                                                                                                </div>
                                                                                                              </div>
                                                                                                            </div>
                                                                                                            
                                                                                                            
                                                                                                              - LOCAL_PATH := $(call my-dir)
                                                                                                              
                                                                                                              - 
                                                                                                              - include $(CLEAR_VARS)
                                                                                                              
                                                                                                              - 
                                                                                                              - LOCAL_MODULE    := DataProvider
                                                                                                              
                                                                                                              - LOCAL_SRC_FILES := DataProvider.c
                                                                                                              
                                                                                                              - #增加log函数对应的log库
                                                                                                              
                                                                                                              - LOCAL_LDLIBS += -llog
                                                                                                              
                                                                                                              - 
                                                                                                              - include $(BUILD_SHARED_LIBRARY)
                                                                                                              
                                                                                                            
                                                                                                          </div>
                                                                                                          
                                                                                                          

                                                                                                            &#8212;**DataProvider.c 主程序源码** :</div> 
                                                                                                            
                                                                                                            <div>
                                                                                                              <div class="dp-highlighter bg_cpp">
                                                                                                                <div class="bar">
                                                                                                                  <div class="tools">
                                                                                                                    **[cpp]** [view plain](http://blog.csdn.net/shulianghan/article/details/18964835#)[copy](http://blog.csdn.net/shulianghan/article/details/18964835#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/181707)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/181707/fork)

                                                                                                                    
                                                                                                                    <div>
                                                                                                                      <embed id="ZeroClipboardMovie_46" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_46">
                                                                                                                      </embed>
                                                                                                                    </div>
                                                                                                                  </div>
                                                                                                                </div>
                                                                                                                
                                                                                                                
                                                                                                                  - <span class="preprocessor">#include <jni.h></span>
                                                                                                                  
                                                                                                                  - <span class="preprocessor">#include <string.h></span>
                                                                                                                  
                                                                                                                  - <span class="preprocessor">#include <android/log.h></span>
                                                                                                                  
                                                                                                                  - <span class="preprocessor">#define LOG_TAG &#8220;System.out&#8221;</span>
                                                                                                                  
                                                                                                                  - <span class="preprocessor">#define LOGD(&#8230;) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)</span>
                                                                                                                  
                                                                                                                  - <span class="preprocessor">#define LOGI(&#8230;) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)</span>
                                                                                                                  
                                                                                                                  - 
                                                                                                                  - <span class="comment">// java中的jstring, 转化为c的一个字符数组</span>
                                                                                                                  
                                                                                                                  - <span class="datatypes">char</span>* Jstring2CStr(JNIEnv* env, jstring jstr) {
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//声明了一个字符串变量 rtn</span>
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="datatypes">char</span>* rtn = NULL;
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//找到Java中的String的Class对象</span>
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>jclass clsstring = (*env)->FindClass(env, <span class="string">&#8220;java/lang/String&#8221;</span>);
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//创建一个Java中的字符串 &#8220;GB2312&#8221;</span>
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>jstring strencode = (*env)->NewStringUTF(env, <span class="string">&#8220;GB2312&#8221;</span>);
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">/*</span>
                                                                                                                  
                                                                                                                  - <span class="comment"><span style=&#8221;white-space:pre&#8221;>  </span> * 获取String中定义的方法 getBytes(), 该方法的参数是 String类型的, 返回值是 byte[]数组</span>
                                                                                                                  
                                                                                                                  - <span class="comment"><span style=&#8221;white-space:pre&#8221;>  </span> * &#8220;(Ljava/lang/String;)[B&#8221; 方法前面解析 :</span>
                                                                                                                  
                                                                                                                  - <span class="comment"><span style=&#8221;white-space:pre&#8221;>  </span> * &#8212; Ljava/lang/String; 表示参数是String字符串</span>
                                                                                                                  
                                                                                                                  - <span class="comment"><span style=&#8221;white-space:pre&#8221;>  </span> * &#8212; [B : 中括号表示这是一个数组, B代表byte类型, 返回值是一个byte数组</span>
                                                                                                                  
                                                                                                                  - <span class="comment"><span style=&#8221;white-space:pre&#8221;>  </span> */</span>
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>jmethodID mid = (*env)->GetMethodID(env, clsstring, <span class="string">&#8220;getBytes&#8221;</span>,
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>          </span><span class="string">&#8220;(Ljava/lang/String;)[B&#8221;</span>);
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//调用Java中的getBytes方法, 传入参数介绍 参数②表示调用该方法的对象, 参数③表示方法id , 参数④表示方法参数</span>
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid,
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>          </span>strencode); <span class="comment">// String .getByte(&#8220;GB2312&#8221;);</span>
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//获取数组的长度</span>
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>jsize alen = (*env)->GetArrayLength(env, barr);
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//获取数组中的所有的元素 , 存放在 jbyte*数组中</span>
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="comment">//将Java数组中所有元素拷贝到C的char*数组中, 注意C语言数组结尾要加一个 &#8216;\0&#8217;</span>
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="keyword">if</span> (alen > 0) {
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>      </span>rtn = (<span class="datatypes">char</span>*) malloc(alen + 1); <span class="comment">//new   char[alen+1]; &#8220;\0&#8221;</span>
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>      </span>memcpy(rtn, ba, alen);
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>      </span>rtn[alen] = 0;
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>}
                                                                                                                  
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span>(*env)->ReleaseByteArrayElements(env, barr, ba, 0); <span class="comment">//释放内存</span>
                                                                                                                  
                                                                                                                  - 
                                                                                                                  - 
                                                                                                                  - <span style=<span class="string">&#8220;white-space:pre&#8221;</span>>  </span><span class="keyword">return</span> rtn;
                                                                                                                  
                                                                                                                  - }
                                                                                                                  
                                                                                                                  - 
                                                                                                                  - <span class="comment">//方法签名, Java环境 和 调用native方法的类 必不可少, 后面的参数就是native方法的参数</span>
                                                                                                                  
                                                                                                                  - jint Java_shuliang_han_ndkparameterpassing_DataProvider_add(JNIEnv * env, jobject obj, jint x, jint y)
                                                                                                                  
                                                                                                                  - {
                                                                                                                  
                                                                                                                  - <span class="comment">//Java中的int对应的是C语言中的long类型, 对应JNI中的jint类型, C语言中</span>
                                                                                                                  
                                                                                                                  - LOGI(<span class="string">&#8220;JNI_log : x = %d , y = %d&#8221;</span> , x , y);
                                                                                                                  
                                                                                                                  - <span class="keyword">return</span> x + y;
                                                                                                                  
                                                                                                                  - }
                                                                                                                  
                                                                                                                  - 
                                                                                                                  - jstring Java_shuliang_han_ndkparameterpassing_DataProvider_sayHelloInc(JNIEnv *env, jobject obj, jstring str)
                                                                                                                  
                                                                                                                  - {
                                                                                                                  
                                                                                                                  - <span class="datatypes">char</span> *p = (<span class="datatypes">char</span>*)Jstring2CStr(env, str);
                                                                                                                  
                                                                                                                  - <span class="comment">//打印Java传递过来的数据</span>
                                                                                                                  
                                                                                                                  - LOGI(<span class="string">&#8220;Java JNI string parameter is : %s&#8221;</span>, p);
                                                                                                                  
                                                                                                                  - 
                                                                                                                  - <span class="datatypes">char</span> *append = <span class="string">&#8220;append&#8221;</span>;
                                                                                                                  
                                                                                                                  - 
                                                                                                                  - <span class="comment">//strcat(dest, source) 函数可以将source字符串 添加到dest字符串后面</span>
                                                                                                                  
                                                                                                                  - <span class="keyword">return</span> (*env)->NewStringUTF(env, strcat(p, append));
                                                                                                                  
                                                                                                                  - }
                                                                                                                  
                                                                                                                  - 
                                                                                                                  - jintArray Java_shuliang_han_ndkparameterpassing_DataProvider_intMethod(JNIEnv *env, jobject obj, jintArray arr)
                                                                                                                  
                                                                                                                  - {
                                                                                                                  
                                                                                                                  - <span class="comment">//获取arr大小</span>
                                                                                                                  
                                                                                                                  - <span class="datatypes">int</span> len = (*env)->GetArrayLength(env, arr);
                                                                                                                  
                                                                                                                  - 
                                                                                                                  - <span class="comment">//在LogCat中打印出arr的大小</span>
                                                                                                                  
                                                                                                                  - LOGI(<span class="string">&#8220;the length of array is %d&#8221;</span>, len);
                                                                                                                  
                                                                                                                  - 
                                                                                                                  - <span class="comment">//如果长度为0, 返回arr</span>
                                                                                                                  
                                                                                                                  - <span class="keyword">if</span>(len == 0)
                                                                                                                  
                                                                                                                  - <span class="keyword">return</span> arr;
                                                                                                                  
                                                                                                                  - 
                                                                                                                  - <span class="comment">//如果长度大于0, 那么获取数组中的每个元素</span>
                                                                                                                  
                                                                                                                  - jint* p = (*env)->GetIntArrayElements(env, arr, 0);
                                                                                                                  
                                                                                                                  - 
                                                                                                                  - <span class="comment">//打印出数组中每个元素的值</span>
                                                                                                                  
                                                                                                                  - <span class="datatypes">int</span> i = 0;
                                                                                                                  
                                                                                                                  - <span class="keyword">for</span>(; i < len; i ++)
                                                                                                                  
                                                                                                                  - {
                                                                                                                  
                                                                                                                  - LOGI(<span class="string">&#8220;arr[%d] = %d&#8221;</span>, i, *(p + i));
                                                                                                                  
                                                                                                                  - }
                                                                                                                  
                                                                                                                  - 
                                                                                                                  - <span class="keyword">return</span> arr;
                                                                                                                  
                                                                                                                  - 
                                                                                                                  - }
                                                                                                                  
                                                                                                                
                                                                                                              </div>
                                                                                                            </div>
                                                                                                            
                                                                                                            <div>
                                                                                                              .
                                                                                                            </div>
                                                                                                            
                                                                                                            <div>
                                                                                                            </div>
                                                                                                            
                                                                                                            <div>
                                                                                                            </div>
                                                                                                            
                                                                                                            <div>
                                                                                                            </div>
                                                                                                            
                                                                                                            <div>
                                                                                                              ## <a name="t50"></a>8. 上传代码到GitHub
                                                                                                              
                                                                                                              

                                                                                                                **创建新项目** : han1202012/NDKParameterPassing ;

SSH地址 : git@github.com:han1202012/NDKParameterPassing.git ; — HTTP地址 : https://github.com/han1202012/NDKParameterPassing.git ;