Linux安全网 - Linux操作系统_Linux 命令_Linux教程_Linux黑客

会员投稿 投稿指南 本期推荐:
搜索:
您的位置: Linux安全网 > Linux编程 > » 正文

Step By Step(Java 本地方法篇)

来源: 未知 分享至:

    本篇是该系列的最后一篇文章,就让我们以JNI作为结束吧!

    众所周知,使用多种语言协同开发时,经常会导致一些未知问题的发生,也会给我们程序的调试带来一定的负担。鉴于此,我们也只有在充分了解到必要性之后再决定用C/C++来替换部分Java代码,以达到我们预期的目的,考虑使用本地代码主要有以下三个理由:
    1)    你的应用需要访问系统的各个特性和设备,这些特性和设备通过Java平台是无法访问的;
    2)    你已经有了大量的测试过和调试过得用另一种语言编写的代码,并且知道如何将其导出到所有的目标平台上;
    3)    通过基准测试,你已经发现所编写的Java代码比用其他语言编写的等价代码要慢得多。
    在Java中提供了用于和本地C语言代码进行互操作的API,称为Java本地接口(JNI)。
       
    1.    第一个本地方法:
    1)    声明一个含有本地方法的类:

1     public class HelloNative {
2 public static native void greeting();
3 }

    注意以上代码中的native关键字,以及在函数声明的末尾直接用分号结束该函数的声明。
    2)    将该.java文件编译成.class文件,如果使用eclipse直接用IDE编译即可,否则可以使用命令行:
    javac HelloNative.java
    将会发现在当前目录下生成了相应的HelloNative.class文件。
    3)    通过%JAVA_HOME%/bin/javah命令在命令行窗口为HelloNative.class文件生成相应的C语言使用的头文件。
    javah HelloNative  #这里不要添加.class后缀,执行目录为HelloNative.class所在的目录。
    需要注意的是,在我们的例子中并没有给HelloNative方法添加包名,如:

1     package mytest;
2 public class HelloNative {
3 public static native void greeting();
4 }

    针对该种情况在基于.class文件生成C语言要求的头文件时,需要做出以下调整:
    javah mytest.HelloNative     #这里在类的前面添加了包名mytest,包名和类名之间使用dot作为连接符。还需要注意的是执行当前命令的目录为HelloNative.class所在目录的上一级目录,如果包的名字为package mytest.first; 则执行目录为HelloNative.class的上两级目录,以此类推。执行成功后将会在当前执行目录下生成一个名为mytest_HelloNative.h(针对包名为mytest的case)。该文件中包含了和HelloNative.greeting()对应的C语言导出函数的声明。为了实现本地代码,要求生成的C函数名符合Java在JNI中定义的命名规则,如:
    1)    使用完整的Java类名.方法名,如:HelloNative.greeting。如果类属于某个包,那么在前面添加包名,如mytest.HelloNative.greeting;
    2)    用下划线替换掉所有的dot,并加上Java_前缀,如:Java_mytest_HelloNative_greeting;
    3)    如果你重载本地方法,既使用相同名字提供多个本地方法,那么必须在名称后附加两个下划线,后面再加上已编码的参数类型。如:Java_mytest_HelloNative_greeting__表示当前没有参数的greeting,如果在Java中同时定义了另一个greeting(int repeat),其对应的C函数声明为Java_mytest_HelloNative_greeting__I,这里的I表示参数类型,更为具体的描述,后面会逐步给出。
    以下为该头文件的代码:   

 1     /* DO NOT EDIT THIS FILE - it is machine generated */
2 #include <jni.h>
3 /* Header for class mytest_HelloNative */
4 #ifndef _Included_mytest_HelloNative
5 #define _Included_mytest_HelloNative
6 #ifdef __cplusplus
7 extern \"C\" {
8 #endif
9 /*
10 * Class: mytest_HelloNative
11 * Method: greeting
12 * Signature: ()V
13 */
14 JNIEXPORT void JNICALL Java_mytest_HelloNative_greeting
15 (JNIEnv *, jclass);
16
17 #ifdef __cplusplus
18 }
19 #endif
20 #endif

    我们后面需要做的是为该头文件创建一个对应的HelloNative.c文件包含导出函数的实现代码,如:

1     #include \"HelloNative.h\"
2 #include <stdio.h>
3 JNIEXPORT void JNICALL Java_mytest_HelloNative_greeting(JNIEnv* env, jclass cl) {
4 printf(\"Hello Native World!n\");
5 }

    注意如果使用了C++的代码,由于Java并未提供和C++的交互能力,因此需要在该函数前加extern \"C\"来表示按照C语言的方法导出,以阻止编译器生成C++特有的代码,如:

1     extern \"C\"    
2 JNIEXPORT void JNICALL Java_mytest_HelloNative_greeting(JNIEnv*

Tags:
分享至:
最新图文资讯
1 2 3 4 5 6
验证码:点击我更换图片 理智评论文明上网,拒绝恶意谩骂 用户名:
关于我们 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 发展历史