java调用c动态库jni_JAVA使用JNI调用C/C++动态库[转]

转自:http://blog.csdn.net/jtlyr/article/details/4389926

在实际使用中,我们经常会在JAVA和C/C++之间进行交互,比较通用的方法目前是使用JNI接口进行。

根据我在项目中使用的方法并结合icecreamchen的《JNI调用小结》,总结以下经验。

=====================================================

一.     什么是JNI?

JNI是Java Native Interface的缩写。从Java1.1开始,JNI标准成为Java平台的一部分。通过JNI,可以实现Java和其他的语言代码的交互,常用的是Java和C/C++之间的交互。

二.     JNI的使用方法

这里以Helloworld.java调用HelloWorld.dll/HelloWorld.so为例,讲述JNI的使用方法。

1.      创建一个class(HelloWorld.java),并声明一个native方法;

2.      使用javac编译该class(HelloWorld.java),生成HelloWorld.class;

3.      使用javah –jni生成C 头文件,其中包含native方法的原型。

4.      使用C/C++实现native方法(HelloWorld.c/ HelloWorld.cpp)。

5.      编译C代码(HelloWorld.c),创建动态库文件(HelloWorld.dll(for Windows)或者HelloWorld.so(for Linux));

6.      使用java类(HelloWorld.java),加载C动态库文件和native方法,实现二者交互。

下图是JNI的使用方法进行图例化解释:

图1 JNI使用方法

三.     JNI应用实例

根据“二.JNI的使用方法”中介绍的步骤,我们做几个实例。

1.      简单的实例

1)      创建一个class,名称就用HelloWorld.java,并声明一个native方法;

public class HelloWorld {

static {

System.loadLibrary("HelloWorld");

}

private native void setMsg(String str);

private native String getMsg();

public static void main(String[] argv) {

HelloWorld hw = new HelloWorld();

hw.setMsg("HelloWorld");

System.out.println(hw.getMsg());

}

}

2)      执行javac HelloWorld.java命令,生成HelloWorld.class;

3)      执行javah –jni HelloWorld命令,生成HelloWorld.h,其内容如下:

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

#include

/* Header for class HelloWorld */

#ifndef _Included_HelloWorld

#define _Included_HelloWorld

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class:     HelloWorld

* Method:    setMsg

* Signature: (Ljava/lang/String;)V

*/

JNIEXPORT void JNICALL Java_HelloWorld_setMsg

(JNIEnv *, jobject, jstring);

/*

* Class:     HelloWorld

* Method:    getMsg

* Signature: ()Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_HelloWorld_getMsg

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

需要注意的是Java中的类型发生了变化,另外native方法前面增加了前缀。

4)      创建HelloWorld.cpp文件,在此我们使用VC++6.0做成HelloWorld.cpp;

// HelloWorld.cpp : Defines the entry point for the DLL application.

//

#include "stdafx.h"

#include "HelloWorld.h"

char far* str;

JNIEXPORT void JNICALL Java_HelloWorld_setMsg

(JNIEnv *env, jobject obj, jstring jstr) {

str = (char far*)env->GetStringUTFChars(jstr, NULL);

}

JNIEXPORT jstring JNICALL Java_HelloWorld_getMsg

(JNIEnv *env, jobject obj) {

jstring jstr;

jstr = env->NewStringUTF(str);

return jstr;

}

5)      编译HelloWorld.cpp,生成HelloWorld.dll;

6)      执行java HelloWorld命令,得到如下结果:

2.      带Package的实例

通常我们使用的source都是在某个Package中,这种情况下的处理稍有不同。还是以上面的示例为例,简单说明一下。

1)      创建一个class,名称就用HelloWorld.java,Package为jp.co.test,并声明一个native方法;

package jp.co.test;

public class HelloWorld {

static {

System.loadLibrary("HelloWorld");

}

private native void setMsg(String str);

private native String getMsg();

public static void main(String[] argv) {

HelloWorld hw = new HelloWorld();

hw.setMsg("HelloWorld");

System.out.println(hw.getMsg());

}

}

2)      在jp/co/test/目录下使用javac HelloWorld.java命令,编译生成HelloWorld.class文件;

3)      此步稍有不同的是要在source Folder路径下执行javah jp.co.test.HelloWorld命令,执行成功后,也会在source Folder路径下生成jp_co_test_HelloWorld.h文件,其内容如下:

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

#include

/* Header for class jp_co_test_HelloWorld */

#ifndef _Included_jp_co_test_HelloWorld

#define _Included_jp_co_test_HelloWorld

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class:     jp_co_test_HelloWorld

* Method:    setMsg

* Signature: (Ljava/lang/String;)V

*/

JNIEXPORT void JNICALL Java_jp_co_test_HelloWorld_setMsg

(JNIEnv *, jobject, jstring);

/*

* Class:     jp_co_test_HelloWorld

* Method:    getMsg

* Signature: ()Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_jp_co_test_HelloWorld_getMsg

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

4)      创建HelloWorld.cpp文件,native方法名要和jp_co_test_HelloWorld.h中的一致;

5)      编译HelloWorld.cpp,生成HelloWorld.dll;

6)      把HelloWorld.dll copy到source Folder路径下,执行java jp.co.test.HelloWorld得到如下结果:

四.     结束语

至此,JNI的基本使用方法介绍完了,但在实际使用中可能还会存在各种各样的问题,如其他操作系统(如:Linux)下的使用方法,传递中文字符的问题,传递复杂类型的问题等等,这需要大家不断深入探讨和钻研,方可熟练运用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值