Java调用C/C++编写的第三方dll动态链接库

本文介绍如何在Java中通过JNI调用外部DLL文件,并提供了一个详细的步骤指南,包括生成和编译C++代码,最终实现在Java项目中使用DLL中的函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://developer.51cto.com/art/201201/311363.htm


最近在用weka做一个数据挖掘相关的项目,不得不说,weka还是一个不错的开放源代码库,提供了很多最常用的分类和聚类算法。

在我的项目中要用到一个聚类算法,Affinity Propagation(AP),由多伦多大学的Brendan J. Frey发表于2007年。相比其他的聚类算法,AP算法的聚类结果更加准确。

在AP的官方网站公布了AP算法的动态链接库,我的目标就是实现在Java工程中调用这个动态链接库。

在网上查了资料,发现,如果仅仅是想调用Windows的Native API还是比较省事的,这里我主要针对第三方dll的调用。

下面进入正题。

这里主要用的方法是JNI。在网上查资料时看到很多人说用JNI非常的复杂,不仅要看很多的文档,而且要非常熟悉C/C++编程。恐怕有很多人在看到诸如此类的评论时已经决定绕道用其他方法了。但是,假如你要实现的功能并不复杂(简单的参数传递,获取返回值等等),我还是支持使用这个方法的。

Java Native Interface,简称JNI,是Java平台的一部分,可用于让Java和其他语言编写的代码进行交互。下面是从网上摘取的JNI工作示意图。


图1 JNI的工作模式




下面就举具体的例子说明一下使用步骤:

(一)JAVA中所需要做的工作

例如程序testdll.java,内容为:

package p1.test
public class testdll
{
 //在JAVA程序中,首先需要在类中声明所调用的库名称。在这里,库的扩展名字可以不用写出来,究竟是DLL还是SO,由系统自己判断。
 static
 {
  System.loadLibrary("hello");
 }
 //还需要对将要调用的方法做本地声明,关键字为native。并且只需要声明,而不需要具体实现。
 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());
 }
}


然后编译该JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就会生成C/C++的头文件。



其中D:\software\JAVA\android-sdk_r24.0.2\android-sdk-windows\eclipse\workspace\DEMO1\src\p1\test\目录下生成了testdll.java


2.编译生成.h文件


(一)生成class文件

 cmd进入

cd D:\software\JAVA\android-sdk_r24.0.2\android-sdk-windows\eclipse\workspace\DEMO1\src
javac p1.test.testdll.java


生成testdll.class

(二)生成.h文件

cd D:\software\JAVA\android-sdk_r24.0.2\android-sdk-windows\eclipse\workspace\DEMO1\src
javah -classpath D:\software\JAVA\android-sdk_r24.0.2\android-sdk-windows\eclipse\workspace\DEMO1\src p1.test.testdll 


在D:\software\JAVA\android-sdk_r24.0.2\android-sdk-windows\eclipse\workspace\DEMO1\src\p1\test目录下生成testdll .h文件

或者

(1)javah -classpath D:\software\JAVA\android-sdk_r24.0.2\android-sdk-windows\eclipse\workspace\DEMO1\src -jni p1.test.testdll // D:\software\JAVA\android-sdk_r24.0.2\android-sdk-windows\eclipse\workspace\DEMO1\src\p1\test目录下生成testdll .h文件

(2)  javah -classpath D:\software\JAVA\android-sdk_r24.0.2\android-sdk-windows\eclipse\workspace\DEMO1\src  -d d:/  -jni  p1.test.testdll   //在D:\目录下生成testdll .h文件

3.编写C++代码

打开VC++首先新建一个Win32 Dynamic-Link library工程,之后选择An empty DLL project空工程。在这里我C++的工程是hello,把刚刚生成的那个头文件拷贝到这个工程的根目录里。

(1) 在VC工程下添加JDK的include路径

   工程右键->属性->VC目录->包含目录 加入D:\Program Files (x86)\JAVA_JDK_J2SE\include   和D:\Program Files (x86)\JAVA_JDK_J2SE\include\win32

(2)新建一个C++ source file  p1_test_testdll.cpp来实现这个方法。

#include"test_lily2_testdll.h"


int i = 0;
JNIEXPORT jint JNICALL Java_test_lily2_testdll_get(JNIEnv *, jclass)
{
	return i;
}
JNIEXPORT void JNICALL Java_test_lily2_testdll_set(JNIEnv *, jclass, jint j)
{
	i = j;
}

(3)f7编译,生成hello.dll

(4)将hello.dll放入java工程目录下D:\software\JAVA\android-sdk_r24.0.2\android-sdk-windows\eclipse\workspace\DEMO1




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值