微科社区,轻松开发从此开始! 请登陆 免费注册

微科社区

当前位置:首页 > Java平台 > J2EE >

使用JNI进行Java与C/C++语言混合编程(1)--在Java中调

时间:2017-01-13 03:27  浏览:努力统计中...
JNI系列文章索引 使用JNI进行Java与C/C++语言混合编程(1)--在Java中调用C/C++本地库 使用JNI进行Java与C/C++语言混合编程(2)--在C/C++中调用Java代码 JNI是Java Native Interface的英文缩写, 中文翻译为本

JNI系列文章索引

  1. 使用JNI进行Java与C/C++语言混合编程(1)--在Java中调用C/C++本地库

  2. 使用JNI进行Java与C/C++语言混合编程(2)--在C/C++中调用Java代码

JNI是Java Native Interface的英文缩写, 中文翻译为本地调用, 自从Java 1.1开始就成为了Java标准的一部分.

C/C++是系统级的编程语言, 可以用来开发任何和系统相关的程序和类库, 但是Java本身编写底层的应用比较难实现, 使用JNI可以调用现有的本地库, 极大地灵活了Java的开发.

C/C++的效率是目前最好的语言, 可以使用C/C++来实现一些实时性非常高的部分. C/C++和Java本身都是非常流行的编程语言, 一些大型软件中经常使用语言之间的混合编程.

鉴于目前网络上JNI的文章不是特别多, 我将自己的一些总结写在这里. 如有错漏, 欢迎指正!

Java调用C/C++大概有这样几个步骤

  1. 编写带有native方法的Java类, 使用javac工具编译Java类
  2. 使用javah来生成与native方法对应的头文件
  3. 实现相应的头文件, 并编译为动态链接库(windows下是.dll, linux下是.so)

下面就完整的介绍一个简单的Java调用C/C++的例子, 这个例子是来自http://www.ibm.com/developerworks/cn/education/java/j-jni/index.html, 不过其中有一些错误, 这个文章是非常不错的JNI学习资料, 但是非常古老.

编写Java类

我们来编写一个Sample1的java类

public class Sample1 {	public native int intMethod(int n);	public native boolean booleanMethod(boolean bool);	public native String stringMethod(String text);	public native int intArrayMethod(int[] intArray);		public static void main(String[] args) {		System.loadLibrary("Sample1");		Sample1 sample = new Sample1();		int square = sample.intMethod(5);		boolean bool = sample.booleanMethod(true);		String text = sample.stringMethod("Java");		int sum = sample.intArrayMethod(new int[]{1,2,3,4,5,8,13});				System.out.println("intMethod: " + square);		System.out.println("booleanMethod: " + bool);		System.out.println("stringMethod: " + text);		System.out.println("intArrayMethod: " + sum);	}}

上面有4个native方法, 分别是4种类型的参数, int, boolean, String, int[].

其中有一句比较重要, 这句话加载了动态类库

System.loadLibrary("Sample1");

在windows下加载的就是Sample1.dll, 在linux下加载的就是Sample1.so.

本文使用的windowws, 所以后面使用Sample1.dll来表示Sample1动态链接库.

注意: 不可以在代码中写上后缀dll或so. 还要保证Sample1.dll在path路径中. 这个Sample1.dll是我们后面需要编译出来的东西.

4个native方法就是我们需要用C来实现的方法.

编译Sample1.java, 使用命令行(windows是cmd, linux下一般是bash)

>javac Sample1.java

可以看到Sample1.class文件

使用javah生成头文件

在命令行中运行

>javah Sample1

可以在目录下看到一个新文件Sample1.h

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class Sample1 */#ifndef _Included_Sample1#define _Included_Sample1#ifdef __cplusplusextern "C" {#endif/* * Class:     Sample1 * Method:    intMethod * Signature: (I)I */JNIEXPORT jint JNICALL Java_Sample1_intMethod  (JNIEnv *, jobject, jint);/* * Class:     Sample1 * Method:    booleanMethod * Signature: (Z)Z */JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod  (JNIEnv *, jobject, jboolean);/* * Class:     Sample1 * Method:    stringMethod * Signature: (Ljava/lang/String;)Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_Sample1_stringMethod  (JNIEnv *, jobject, jstring);/* * Class:     Sample1 * Method:    intArrayMethod * Signature: ([I)I */JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod  (JNIEnv *, jobject, jintArray);#ifdef __cplusplus}#endif#endif

我们可以看到其中有四个函数声明, Java_完整类名_方法名, 完整类名包括了包名, 例如demo.Sample1是完整类名, 对应的这里就是demo_Sample1.

在注释中我们可以看到这样一个东西 Signature, 这个是方法的签名. 关于Signature, 下面通过一个表格来说明.


java类型
顶一下
(1)
100%
踩一下
(0)
0%
------分隔线------
推荐内容