mingjava的专栏

The world need more people who are crazy

原创 JNI入门教程之HelloWorld篇 收藏

新一篇: 推荐给XML初学者的一些站点

   本文讲述如何使用JNI技术实现HelloWorld,目的是让读者熟悉JNI的机制并编写第一个HelloWorld程序。

    Java Native Interface(JNI)是Java语言的本地编程接口,是J2SDK的一部分。在java程序中,我们可以通过JNI实现一些用java语言不便实现的功能。通常有以下几种情况我们需要使用JNI来实现。

  • 标准的java类库没有提供你的应用程序所需要的功能,通常这些功能是平台相关的
  • 你希望使用一些已经有的类库或者应用程序,而他们并非用java语言编写的
  • 程序的某些部分对速度要求比较苛刻,你选择用汇编或者c语言来实现并在java语言中调用他们

    在《java核心技术》中,作者提到JNI的时候,建议不到万不得已不要使用JNI技术,一方面它需要你掌握更多的知识才可以驾驭,一方面使用了JNI你的程序就会丧失可移植性。在本文我们跳过JNI的底层机制,读者最好先把它想象为本地代码和java代码的粘合剂。关系如下图所示:

 

 

 

 





 

 

 

    下面我们开始编写HelloWorld程序,由于涉及到要编写c/c++代码因此我们会在开发中使用Microsoft VC++工具。

  1. 编写java代码
    我们在硬盘上建立一个hello目录作为我们的工作目录,首先我们需要编写自己的java代码,在java代码中我们会声明native方法,代码非常简单。如下所示
    class HelloWorld
    {
        public native void displayHelloWorld();
        static {
            System.loadLibrary("hello");
        }
       
        public static void main(String[] args) {
            new HelloWorld().displayHelloWorld();
        }
    }
    注意我们的displayHelloWorld()方法的声明,它有一个关键字native,表明这个方法使用java以外的语言实现。方法不包括实现,因为我们要用c/c++语言实现它。注意System.loadLibrary("hello")这句代码,它是在静态初始化块中定义的,系统用来装载hello共享库,这就是我们在后面生成的hello.dll(如果在其他的操作系统可能是其他的形式,比如hello.so)
  2. 编译java代码
    javac HelloWorld.java  生成HelloWorld.class文件
  3. 创建.h文件
    这一步中我们要使用javah命令生成.h文件,这个文件要在后面的c/c++代码中用到,我们运行
    javah HelloWorld。这样我们可以看到在相同目录下生成了一个HelloWorld.h文件,文件内容如下
    在此我们不对他进行太多的解释。
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class HelloWorld */
    #ifndef _Included_HelloWorld
    #define _Included_HelloWorld
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     HelloWorld
     * Method:    displayHelloWorld
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
      (JNIEnv *, jobject);
    #ifdef __cplusplus
    }
    #endif
    #endif
  4. 编写本地实现代码
    在这部分我们要用C/C++语言实现java中定义的方法,我们在VC++中新建一个Project,然后创建一个HelloWorldImp.cpp文件,内容如下
    #include <jni.h>
    #include "HelloWorld.h"
    #include <stdio.h>

    JNIEXPORT void JNICALL
    Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
    {
        printf("Hello world!\n");
        return;
    }
    注意我们这里include了 jni.h和刚才得到的HelloWorld.h文件。因此你要在VC++里面设置好,jni.h在JAVA_HOME/include里面。编译通过后再生成hello.dll文件。
  5. 运行java程序
    把上面生成的hello.dll文件复制到我们的工作目录,这时候我们的目录中包括HelloWorld.java,HelloWorld.class和hello.dll文件。运行java HelloWorld命令,则可在控制台看到Hello world|
    的输出了。

    JNI是一门复杂,有趣且富有挑战性的技术,我们在后面的几篇文章中将说明如何在java语言和Native语言之间进行交互。

发表于 @ 2004年11月14日 08:59:00|评论(loading...)|编辑

旧一篇: J2ME开发网推出java手机列表栏目,方便开发者查询

评论

#liupopo 发表于2004-11-22 20:09:00  IP: 219.148.40.*
好文,继续啊。。。。
#night 发表于2004-12-20 18:24:00  IP: 61.153.0.*
非常适合初学者看啊,请继续下文
#NetSniffer 发表于2005-02-21 11:50:00  IP: 218.17.223.*
如果调用已有的DLL文件,则还得自己写一个DLL,在这个DLL里边按JNI的导出格式声明导出函数,此DLL里边再调用已有的DLL。
#achengz 发表于2005-03-25 00:20:00  IP: 222.94.188.*
谢谢楼主啦!
今天遇到native的问题,搜索到这篇文章,按照楼主的说法,依葫芦画瓢做了一遍,对native增加了感性认识,再次表示感谢!!
#magicwind 发表于2005-04-15 13:12:00  IP: 218.80.227.*
图片看不到了。
#justin_lin 发表于2005-04-27 17:27:00  IP: 220.130.148.*
太棒了~簡潔有力,好理解~
期待續集~
#tdm 发表于2005-05-16 15:22:00  IP: 219.239.227.*
如何生成 *.dll文件?我在VC++你总是生不出来
#honeysuckle 发表于2005-05-20 11:08:00  IP: 202.114.70.*
javah -classpath <Path> ClassName

注意加上-classpath的参数

另外JNI里面对于C++和C的使用是不同的,因此创建.dll时候一定注意cpp还是c文件。
#SnowOnCastle 发表于2005-05-17 11:30:00  IP: 219.144.251.*
可以生成Class文件,无法找到该类来生成h文件,为什么?

D:\javaProjects\matlabLink>javac MassFrame.java

D:\javaProjects\matlabLink>javah MassFrame
Error: Class MassFrame could not be found.

D:\javaProjects\matlabLink>
#SnowOnCastle 发表于2005-05-17 11:31:00  IP: 219.144.251.*
可以生成Class文件,无法找到该类来生成h文件,为什么?

D:\javaProjects\matlabLink>javac MassFrame.java

D:\javaProjects\matlabLink>javah MassFrame
Error: Class MassFrame could not be found.

D:\javaProjects\matlabLink>
#jni 发表于2005-06-05 17:25:00  IP: 61.186.252.*
Exception in thread "main" java.lang.UnsatisfiedLinkError:
#jni 发表于2005-06-05 17:30:00  IP: 61.186.252.*
Exception in thread "main" java.lang.UnsatisfiedLinkError
为什么会这样???
#请教 发表于2005-12-17 18:17:00  IP: 221.11.186.*
你好,我最近用java调用vc动态库,试验时可以通过,但当我把java文件放在一个包里时(package)就提示: Exception in thread "main" java.lang.UnsatisfiedLinkError :。。。 ,请问是怎么回事,期待你的答复。
发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © mingjava