Java JNI 的简单介绍

一,Java JNI 介绍

       Java jni本意是Java native interface(Java本地接口),是为了方便Java调用c、c++等本地代码所封装的一层接口。Java

的优点是跨平台,但是作为优点的同时,其在本地交互的时候就变成了缺点。

        Java的跨平台特性导致其本地交互的能力不够强大,一些和操作系统相关的特性Java无法完成,于是Java提供了jni,专门

用于和本地代码交互,这样就增强了Java语言的本地交互能力。

        通过Java jni,用户可以调用用c、c++所编写的native code。在html5视频和一些与底层系统关联的项目开发中就采用了

jni,android只用于ui的显示,其业务逻辑都是通过native code所完成的,android代码只是负责通过jni和native进行交互,这

样也提高了代码的可维护性。

二,Java JNI 的简单使用

        通过Java jni来调用native code,需要如下几个步骤:

        1,声明native接口函数,语法如下:public native static void set(int i);  其中native是Java的关键字,被native修饰的函

数都是本地函数的接口,其具体功能要被native code来实现。

//testdll.java
public class testdll
{
    static
    {
        System.loadLibrary("my");  //加载本地库文件my.so
    }
    public native static int get();
    public native static void set(int i);
    public static void main(String[] args)
    {
        testdll test = new testdll();
        test.set(3721);
        System.out.println(test.get());
    }
}

        2,用javah命令导出Java jni中定义的本地方法的声明,这个是.h格式的头文件

        首先用javac编译出class文件,然后在用javah导出头文件,我们发现导出的头文件,其函数声明发生了变化,其中jint是jni

定义的用来和c/c++交互的数据类型,可以当作int来用。

//testdll.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class testdll */

#ifndef _Included_testdll
#define _Included_testdll
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     testdll
 * Method:    get
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_testdll_get
  (JNIEnv *, jclass);

/*
 * Class:     testdll
 * Method:    set
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_testdll_set
  (JNIEnv *, jclass, jint);

#ifdef __cplusplus
}
#endif
#endif

        3. 实现Java jni中定义的native methods

        有了头文件以后,就可以用本地函数去实现头文件中声明的native函数了,通常用c和c++来实现native函数。

//my.c
#include "jni.h"
#include "testdll.h"
#include<stdio.h>

static int i;

JNIEXPORT jint JNICALL Java_testdll_get(JNIEnv *a, jclass b)
{
    return i;
}

JNIEXPORT void JNICALL Java_testdll_set(JNIEnv *a, jclass b, jint j)
{
    FILE *f;
    f=fopen("my.txt","a+");
    fwrite("嘿嘿你好啊xixi",1,14,f);
    fclose(f);
    i = j;
}

        4.将native code编译成shared library供Java调用

        针对Linux来说,就是.so文件,针对Windows来说就是.dll文件,Linux下用g++、gcc进行编译,这里不对其进行介绍了。

对Windows来说,编译生成dll一般是通过vc来完成的。Windows下的动态链接库分为win32 dll和mfc dll,其中win32 dll可以

供各种语言调用,而mfc dll则会受到一些限制。这里介绍win32 dll。生成一个win32 dll,要定义被导出的函数,有两种方式,

函数名称前加_declspec(dllexport)或者定义def文件,然后用vc进行编译,这样做并不算复杂,但是我发现了一种更容易的方

法,我们只需要按照c/c++的语法规范实现native函数,不需要定义被导出的函数,然后调用vc的编译工具cl.exe就可以了。首先

将testdll.h和my.c拷贝到Microsoft Visual Studio x.x\VC\bin中,同时将jdk中include目录中的所有文件也都拷贝到Microsoft

Visual Studio x.x\VC\bin中(这样做不是必须的,但是如果不这样,你调用cl命令的时候就要带上一大串路径信息),接着调出

vs再带的命令行工具,进入bin目录,然后执行cl -I . -LD my.c -Femy.dll(.表示当前目录,I表示将在当前目录搜索包含的头文

件,-LD后面表示源文件,-Fe后面紧跟的是目标文件),ok,my.dll生成了,将my.dll拷贝到Java文件所在的目录,执行Java命

令,成功执行。上面只是个简单的示例,实际开发中还会有一些需要注意的问题,比如各种类型参数的传递,native code调用

dll或so的情况,这里就不做介绍了。

转自:http://blog.csdn.net/singwhatiwanna/article/details/9061545

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值