基于jni库Java调用C++的DLL的说明文档

基于jni库Java调用C++的DLL的说明文档

参照网上资料,我们以一个简单的事例讲述如何在window或者linux环境下,Java代码如何调用C++。本文档只测试了window下Java调用DLL是正确的,linux下的so并未验证,但是据资料说用同样的方法即可,不需要区分dll和so。

项目背景

现在有文件setNum.cpp文件,如下:

1
2
3
4
5
6
7
int i = 0;
int get(){
return i;
}
void set(int j){
i = j;
}

那我们如何用java去用set和get方法呢?下面我们来解决这个问题吧。

Java调用C++的方法

概括来说,我们需要做几件事:java采用jni对dll进行引用;基于jni,按照java新生成的.h文件重写编写cpp,并生成相应的新的dll。下面将结合代码详细讲述

1.基于jni,java对已有的dll引用
假设已有有setNum.cpp生成的dll,名为goodluck.dll,我们写testdll.java文件,如下,包括引用dll文件,以及用native定义setNum.cpp内部的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class testdll 
{
static
{
System.loadLibrary("goodluck"); //此处引用的dll
}
public native static int get();
public native static void set(int i);

public static void main(String[] args)
{
testdll test = new testdll();
test.set(10);
System.out.println(test.get());
}
}

2.生成基于jni的新代码

1
2
javac testdll.java //此处生成class文件
javah testdll //此处生成.h文件

java
我们看一下testdll.h代码,请注意里面的文字解说。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* 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); // 此处是基于jni,对testdll.java里的方法进行重写,因此我们需要在cpp文件重写。

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

#ifdef __cplusplus
}
#endif
#endif

3.C/C++重写方法
按照testdll.h文件中的方法命名方式,重写testdll.cpp文件,如下:

1
2
3
4
5
6
7
8
9
#include "StdAfx.h"
#include "testdll.h"
int i = 0;
JNIEXPORT jint JNICALL Java_testdll_get(JNIEnv *, jclass){
return i;
}
JNIEXPORT void JNICALL Java_testdll_set(JNIEnv *, jclass, jint j){
i = j;
}

4.重新生成dll
我是用VC++生成的dll,我想工具是很多的,思路到了就可以啦~。
我在VC++新建了一个win32 Dynamic-Link Library简单的项目,也就是DLL项目,命名为goodluck(很明显抄袭人家,想上面网络资料的作者致谢!)。
将testdll.cpp里面的代码内容覆盖goodluck.cpp,这时候变异运行即可生成dll文件。

但是会出现一些问题,由于jni可能没引入,编译不过去。所以请将下图中jdk的include中的三个文件放在vc++相应的include文件下,在编译即可。
jni
vc

5.运行java文件
最后我们将goodluck项目中生成的goodluck.dll放在与testdll.java同级文件夹下即可。
goodluck
我们运行一下testdll.java文件

java testdll

成功啦

文章目录
  1. 1. 项目背景
  2. 2. Java调用C++的方法