天天看点

JNI技术-1

    什么是JNI呢 就是  java  native interface       是 sun公司提供给我们的一个可以调用本地 非 java语言代码 的接口 . 

    JNI技术 实现了java调用本地方法 ,但是有破坏了 java的 跨平台性 ,因为 java代码可以一次编译处处运行  但是  其他语言则不可以   

    还有java是强类型语言 在进行 数据的传递过程中 参数类型的不同可能会导致错误      

      下面一个简单的例子 实现 java调用  C语言的函数 

      1、首先在java中定义一个  类和 mian函数     用 native关键字 将函数 hello声明为native方法  ,不用对方法进行实现

   public  class NativeTest

{  

 public  native  void hello() ; //java  本地方法

 public static void main(String[] args)

 {

  System.loadLibrary("jnicode") ;  //加载动态链接库  ,注意是动态链接库的名字 

  NativeTest s =new  NativeTest() ; //实例化类

  s.hello() ; //本地方法 也就是 利用C编写的函数调用

 }

}

2、  用过动态链接库的都知道在调用动态链接库的函数的时候 在库内 都有对于函数的声明 ,在JNI中  从java方法到C/C++方法 声明的一个映射 比较麻烦 因此 sun公司

提供了  一个 javah.exe的工具 可以帮助我们生成 与 java本地方法相对应的 C/C++声明   

下面是 javah的用法

用法:javah [选项] <类>  

其中 [选项] 包括:

        -help                 输出此帮助消息并退

        -classpath <路径>     用于装入类的路径

        -bootclasspath <路径> 用于装入引导类的路

        -d <目录>             输出目录

        -o <文件>             输出文件(只能使用

        -jni                  生成 JNI样式的头文

        -version              输出版本信息

        -verbose              启用详细输出

        -force                始终写入输出文件

我们在使用的时候只需要     javah   类名      -jni<可以省略因为是默认参数>     

这样就可以生成一个 对应的.h头文件   ,我们要把类的路径加到classpath中或者 直接进入类所在的文件夹 否则有可能找不到指定的类  

我这里用到的命令是      javah  me.Native.NativeTest    -JNI    会生成 _NativeTest.h的头文件我这里将类放在 me.Native包中

_NativeTest.h内容

#include "jni.h"

#ifndef _Included_me_Native_NativeTest

#define _Included_me_Native_NativeTest

#ifdef __cplusplus

extern "C" {

#endif

JNIEXPORT void JNICALL Java_me_Native_NativeTest_hello

  (JNIEnv *, jobject);

3、 在  VS下创建一个 C/C++的空动态链接库工程  然后 追加头文件   到工程中   ,然后我们再建立一个源文件 吧 头文件中的 函数声明 拷贝到 源文件中 

      源文件代码

#include _me_Native_NativeTest.h"   //包含生成的那个头文件

#include <iostream>

using namespace std ;

JNIEXPORT void JNICALL Java_me_Native_NativeTest_hello(JNIEnv *  env, jobject  obj)

{

   cout<<"hello  world "<<endl ;

4、完成上面的步骤还是不行   我们需要 跑到    JDK  的 安装目录下找到  JNI.H  和  WIN32文件夹下 的 jni_md   拷贝到  工程下  然后   将这2个头文件 拷贝到工程目录下

并且增加到工程中去 。。  这样才算完成了 

OK  一次简单的 JNI调用 C/C++ 函数完成