JNI--Hello World

JNI概述

JNI 是Java Native Interface的缩写,中文译为“Java本地调用”。通常使用JNI技术可以做到以下两点:

(1)Java程序中的函数可以调用Native语言函数,Native函数一般指的是C/C ++编写的函数;

(2)Native程序中的函数可以调用Java层的函数,也就是说在C/C++程序中可以调用Java层函数。

当然任何事物都有两面性,JNI也不例外,使用JNI主要缺点有以下两点:

(1)使用JNI技术将导致Java Application不能跨平台。如果要移植到别的平台上,那么Native代码就要重新进行编写;

(2)Java是强类型的语言,而C/C++不是,因此在编写JNI的时候要非常谨慎。

JNI--Hello World

我们在学习任何一门语言技术时,首先编写的应该是简单的“ Hello World  ”,那么接下来就给大家介绍怎样使用JNI技术来实现Hello World。

(1)首先在Java类中声明一个native的方法

在eclipse中新建一个NativeDemo工程,类名为TestNative,具体代码如下所示:

 

package com.jony.nativetest;

public class TestNative {

    public native void sayHello();
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

}
(2)使用Javah命令生成包含native方法定义的C/C++头文件;

在Java的安装路径(D:\Java\jdk1.6.0_24\bin)中大家可以看到很多可执行文件,其中包含我们常用的java、javac、javah等命令。首先,我们可以简单查看一下javah命令的使用方法,在命令行中输入 javah -help 查看命令参数和使用方法,如图所示:

接下来首先将我们编写的TestNative.java文件编译成class文件,在我本地代码中对应的路径为:E:\Workspaces\android\NativeDemo\bin,具体如图所示:

 

 

在命令提示框中输入:cd E:\Workspaces\android\NativeDemo\bin 和 E: 进入到对应的文件目录,如图所示:

最后在命令提示框中输入 javah com.jony.nativetest.TestNative 命令生成.h头文件,如入所示:


执行完以上命令后,在路径E:\Workspaces\android\NativeDemo\bin下就能查看生成的.h头文件。生成代码如下(com_jony_nativetest_TestNative.h):

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

#ifndef _Included_com_jony_nativetest_TestNative
#define _Included_com_jony_nativetest_TestNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jony_nativetest_TestNative
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_jony_nativetest_TestNative_sayHello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
(3)按照生成的C/C++头文件来写C/C++源文件

首先,在VC++编译器中创建一个Win32 Dynamic-Link Library工程,工程名为NativeCode02,将之前生成的头文件(com_jony_nativetest_TestNative.h)拷贝到NativeCode02项目的根目录。

接下来创建source.cpp文件,目录结构如图所示:

C++代码比较简单,具体代码如上图所示。

(4)将C/C++源文件编译成动态链接库(DLL--可执行的二进制代码)

在进行编译(Ctrl + F5)源文件时,出现以下异常:

--------------------Configuration: NativeCode02 - Win32 Debug--------------------
Compiling...
source.cpp
i:\archive_software\c&c++\vc6.0完整绿色版\myprojects\nativecode02\com_jony_nativetest_testnative.h(2) : fatal error C1083: Cannot open include file: 'jni.h': No such file or directory
执行 cl.exe 时出错.

NativeCode02.dll - 1 error(s), 0 warning(s)

该异常表明在编译的时候没有找到jni.h头文件。在Java的JDK中提供了该头文件,因此我们可以Java安装路径(D:\Java\jdk1.6.0_24\include)找到该头文件,将其拷贝到NativeCode01工程的Header Files目录下

(备注:因为jni.h头文件已经拷贝到本地,因此引用的时候应该将<>替换成" ")再次进行编译(Crtl + F5),出现以下异常:

--------------------Configuration: NativeCode02 - Win32 Debug--------------------
Compiling...
source.cpp
i:\archive_software\c&c++\vc6.0完整绿色版\myprojects\nativecode02\jni.h(27) : fatal error C1083: Cannot open include file: 'jni_md.h': No such file or directory
执行 cl.exe 时出错.

NativeCode02.dll - 1 error(s), 0 warning(s)

该异常也非常容易理解,缺少jni_md.h头文件,同样在Java的安装路径()中找到该头文件并将其拷贝到Header Files目录下,再次进行编译:

--------------------Configuration: NativeCode02 - Win32 Debug--------------------
Compiling...
source.cpp
Linking...
   Creating library Debug/NativeCode02.lib and object Debug/NativeCode02.exp

NativeCode02.dll - 0 error(s), 0 warning(s)

 

OK,编译成功,在工程项目的Debug目录中可以看到我们编译成功的NativeCode02.dll文件。

(5)将动态链接库路径保存在path路径下,这样在Java代码中就可以直接调用该动态链接库(DLL)

具体步骤省略

(6)编写Java层代码

当动态链接库编译成功后,我们就可以在Java层调用该动态链接库了,代码比较简单,直接上代码:

package com.jony.nativetest;

public class TestNative {

    public native void sayHello();
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.loadLibrary("NativeCode02");// 加载动态链接库
        TestNative testNative = new TestNative();
        testNative.sayHello();//调用naive方法
    }
}

OK,大功告成,JNI--Hello World至此已经实现,接下来的博客将给大家深入介绍JNI的使用方式,技术源于分享,大家共同进步……

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值