eclipse java jni_eclipse中JNI实战

1.何为JNI?

JNI是JAVA标准平台中的一个重要功能,它弥补了JAVA的与平台无关这一重大优点的不足,在JAVA实现跨平台的同时,也能与其它语言(如C、C++)的动态库进行交互,给其它语言发挥优势的机会。有了JAVA标准平台的支持,使JNI模式更加易于实现和使用

这里不再赘述,附上别人总结的图:

2011061500160640.png

知识补充:

存根类(stub),它实现了一个接口,但是实现后的每个方法都是空的。

它的作用是:如果一个接口有很多方法,如果要实现这个接口,就要实现所有的方法。但是一个类从业务来说,可能只需要其中一两个方法。如果直接去实现这个接口,除了实现所需的方法,还要实现其他所有的无关方法。而如果通过继承存根类就实现接口,就免去了这种麻烦。

头文件

百度解释:一般会把用来#include的文件的扩展名叫.h,称其为头文件。 #include文件的目的就是把多个编译单元(也就是c或者cpp文件)公用的内容,单独放在一个文件里减少整体代码尺寸;或者提供跨工程公共代码。

2 javah

使用Javah 可以获取您的 Java 源文件并生成 C/C++头文件,其中包含您的 Java

代码中所有本地方法(native方法)的 JNI 存根(stub,C头文件)。

3.eclipse配置javah

JNI的编写步骤

a、编写带有native声明的方法的java类

b、使用javac命令编译a中实现的类

c、javah -jni java类名生成扩展名为h的头文件

d、使用C/C++实现本地方法

e、将d中的本地方法生成动态链接库

首先新建一个包含本地方法(native方法)的类,native标识符暗示这些方法是有实现体的,只不过这些实现体是非java的,代码如下:/**

*

*/

package com.magc.jni;

/**

* @author magc

*

*/

public class HelloWorld {

static {

System.loadLibrary("Hello");

}

public     native void DisplayHello();

/**

* @param args

*/

public static void main(String[] args) {

new HelloWorld().DisplayHello();

}

}

注:

load和loadLibrary区别它们都可以用来装载库文件,不论是JNI库文件还是非JNI库文件。在任何本地方法被调用之前必须先用这个两个方法之一把相应的JNI库文件装载。

2.System.load

参数为库文件的绝对路径,可以是任意路径。

例如你可以这样载入一个windows平台下JNI库文件:

System.load("C:\\Documents

and Settings\\TestJNI.dll");

3. System.loadLibrary

参数为库文件名,不包含库文件的扩展名。

例如你可以这样载入一个windows平台下JNI库文件

System. loadLibrary

("TestJNI");

这里,TestJNI.dll

必须是在java.library.path这一jvm变量所指向的路径中。

可以通过如下方法来获得该变量的值:

System.getProperty("java.library.path");

默认情况下,在Windows平台下,该值包含如下位置:

1)和jre相关的一些目录

2)程序当前目录

3)Windows目录

4)系统目录(system32)

5)系统环境变量path指定目录。

classpath与java.library.path区别

classpath路径下,只能是jar或者class文件,否者会报错,因为他们会被load到JVM中

要想java程序找到共享库还是要在执行java程序的时候指定java.library.path,用eclipse的话可以设置如下:Properties->Run/Debug settings->Arguments->VM arguments

-----------------------------------------

-Djava.library.path=/home/miaoyachun/workspace/JNIC/Release

需要使用外部工具,在我们运行java程序按钮的旁边,或者通过菜单栏上的run选项进入External

tool中并选择 External tool configuration,新建一个启动项HelloWorld

参数如下:

Location:

D:\program

files\Java\jdk1.7.0_51\bin\javah.exe

Working Directory

${project_loc}

Arguments:

-v -classpath "${project_loc}/bin" -d

"${project_loc}/jni" ${java_type_name}  (这里v表示启用详细输出)

fb55d7b77d7d6c76929fd9c687710051.png

4.生成实现函数头文件(扩展名为h)

运行该工具,光标必须定位在在需要生成头文件的java源文件中,否则会报${project_loc}这个变量为空错误

c7c0999295b6e0e8efab6fe5cd197817.png

在当前项目的jni目录下生成了com_magc_jni_HelloWorld.h头文件,此文件供C、C++程序来引用并实现其中的函数/* DO NOT EDIT THIS FILE - it is machine generated */

#include

/* Header for class com_magc_jni_HelloWorld */

#ifndef _Included_com_magc_jni_HelloWorld

#define

_Included_com_magc_jni_HelloWorld

#ifdef __cplusplus

extern "C"

{

#endif

/*

* Class:     com_magc_jni_HelloWorld

* Method:

DisplayHello

* Signature: ()V

*/

JNIEXPORT void JNICALL

Java_com_magc_jni_HelloWorld_DisplayHello

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

注:1)此头文件是不需要用户编译的,直接供其它C、C++程序引用,引用时需改成

include "jni.h"

2)此头文件中的Java_com_magc_jni_HelloWorld_DisplayHello(JNIEnv *, jobject)方法,是将来与动态链接库交互的接口,并需要名字保持一致。

5.使用C/C++实现本地方法生成动态库文件(windows下扩展名为DDL,linux下扩展名为so):

程序代码如下:#include "stdafx.h"

#include "jni.h"

#include "com_magc_jni_HelloWorld.h"

JNIEXPORT void JNICALL Java_com_magc_jni_HelloWorld_DisplayHello

(JNIEnv *env, jobject obj)

{

printf("From jni_helloworldImpl.cpp :");

printf("Hello world ! \n");

return;

}

此C++文件实现了上com_magc_jni_HelloWorld.h头文件中的函数,注意方法名要保持一致。

6. 生成DLL文件,运行HelloWorld.java程序

用visual studio 2015 生成DLL文件,具体怎么生成可参阅这篇博文

将生成的hello.dll文件复制到eclipse项目下,运行控制台成功输出

01eb9b08c9454ad1573765d5f97a70ee.png

21b389ae834cb7d60e627f72eeef45f2.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值