JNI——原生(Native)函数说明和举例

Posted 六楼外的风景

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JNI——原生(Native)函数说明和举例相关的知识,希望对你有一定的参考价值。

1、原生(Native)函数的概念

Java程序中,可以使用由其他编程语言实现的函数,这种函数,在Java中被称之为

原生(Native)函数。

2、Java程序中使用原生函数的优缺点

1)优点

A、Java程序中,可以复用已由其他语言实现的各种库。

可能已存在很多由其他语言编写的库,为了在Java程序中能够复用这些库, 就需要用到原生函数。

B、增加了Java标准类库中不存在的功能

由于Java的可移植性,它不能利用与操作系统相关的特点,因此,当要访问 特定的硬件设备或使用新的网络驱动器时,就不得不使用原生函数提供的功 能。

2)缺点

A、任何包含原生函数的Java类均不能用于Applet程序。

这主要是出于安全性的考虑,因为Java的安全管理机制难以防范来自原生函 数的恶意攻击。

B、使用原生函数将会使Java程序失去可移植性。

因为,你必须为运行该Java程序的各种平台编写不同的原生函数链接库。

3、原生函数的实现步骤

1)JNI接口

JNI接口是Java Native Interface的缩写,它已成为Java平台的一部分,它允许

Java程序中调用由其他语言编写的函数。

JNI接口标准的设计目的有:

A、Java标准类库可能不支持应用程序中需要用到的与平台相关的功能,这部分功 能就需要由JNI来实现。

B、对于已存在的由其他语言编写的库或者应用程序,在Java程序中,可以通过 JNI来实现对这些已存在接口的调用。

C、可能需要用低级语言如汇编来实现一些对运行时间很严格的代码,在Java程序

中,就可以通过JNI接口来调用这些代码。

2)原生函数的实现步骤

A、编写带有native声明的Java类,如test.java

B、使用javac命令编译第一步中编写的java类,如javac test.java,假设生成的文 件为test.class

C、使用javah命令来生成java类对应的存根头文件,如javah -jni test,假设生成 的文件为test.h

D、使用C/C++来实现test.h中的native接口,如test.c

E、test.c编译为动态链接库,如libtest.so

这样,执行命令java test就可以运行了。

4、例子

在这里,我们编写一个最简单的打印hellow world的例子

1、编写一个带有native声明的Java类,如test.java

class TestJni

    public native void myPrint();

    static

    

      System.loadLibrary("hellow");

 //动态链接库的名字(linux下对应为libhellow.so)

    

    public static void main(String args[])

    

     TestJni test = new TestJni();

    

     test.myPrint();

    

2、使用javac命令编译第一步中编写的java

#javac test.java

这条命令将会编译该java程序,并生成相应的字节码文件:TestJni.class

3、使用javah命令来生成java类对应的存根头文件

#javah -jni TestJni

这条命令会根据指定的字节码文件生成相应的存根头文件TestJni.h,其内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class TestJni */

#ifndef _Included_TestJni

#define _Included_TestJni

#ifdef __cplusplus

extern "C" 

#endif

/*

 * Class:     TestJni

 * Method:    myPrint

 * Signature: ()V

 */

JNIEXPORT void JNICALL Java_TestJni_myPrint

  (JNIEnv *, jobject);

#ifdef __cplusplus

#endif

#endif

4、使用C/C++来实现TestJni.h中的native接口,比如将其相应的实现命名为TestJni.c

#include <stdio.h>

#include "TestJni.h"

JNIEXPORT void JNICALL Java_TestJni_myPrint

  (JNIEnv *, jobject)

    printf("Hellow World!/n");

5、将TestJni.c编译为动态链接库

执行命令:

g++ -shared -o libhellow.so TestJni.c -I/usr/lib/jvm/java-6-sun-1.6.0.24/include 

-I/usr/lib/jvm/java-6-sun-1.6.0.24/include/linux/

该命令运行后会生成名为libhellow.so的动态链接库。

注意:生成动态链接库时,头文件路径需要根据具体情况而修改

最后,就可以通过命令执行相应的java程序了(这里一般需要设置环境变量:LD_LIBRARY_PATH,即动态链接库libhellow.so 的路径):

#java TestJni

输出为:Hellow World!

这表明,一切OK

 

参考资料:http://apps.hi.baidu.com/share/detail/5452254

//调用原生函数

以上是关于JNI——原生(Native)函数说明和举例的主要内容,如果未能解决你的问题,请参考以下文章

JNI方法注册源码分析(JNI_OnLoad|动态注册|静态注册|方法替换)

JNI方法注册源码分析(JNI_OnLoad|动态注册|静态注册|方法替换)

JNI方法注册源码分析(JNI_OnLoad|动态注册|静态注册|方法替换)

JNI方法注册源码分析(JNI_OnLoad|动态注册|静态注册|方法替换)

native的认识

android 学习随笔二十七(JNI:Java Native Interface,JAVA原生接口 )