java jna 调用DLL

前言
今天项目上碰到要用Java调用DLL的场景,网上的文章也比较多了,但是自己参照网上的文章来做,却老是报错,最终试了好几个网上的例子,才遇到一个跑得起来的。在搜索文章尝试的时候,就决定,如果搞出来了,一定要写片文章来记录一下过程,由于跨了两种语言,所以,文章尽量傻瓜化,尽量做到demo下载后就能用,这就是这篇博文的由来。
在java调用DLL场景中,一般采用采用jna框架调用,关于jna的具体概念大家自行搜索一下,我自己也一知半解,总之就是一种跨语言调用的工具。

本文涉及到的环境是:win7 64位/MyEclipse 6.5/JDK1.6/VS2010(可选,用来新建DLL因为一般都已经有DLL用来调用了,这里只是为了演示)

需要的资源:jna.jar


本文分以下三部分
一.在VS2010新建一个供调用的DLL
二.在MyEclipse中新建一个JAVA项目并调用DLL
三.总结
----------------------------------------------------------------------------------------------
一、在VS2010新建一个DLL
为了先把调用DLL环境搭好,新建一个简单的DLL是一个比较好的方案,这样可以减少复杂DLL各种引用关系给调试带来的难度,保证调用环境OK.
(1)在VS新建一个解决方案和项目,这里命名为demo,语言选择Visual C++ 框架选择Win32控制台应用,点击确定
java  jna 调用DLL - 安索 - 安索的博客

(2)点击下一步
java  jna 调用DLL - 安索 - 安索的博客

(3)应用程序类型选择DLL,附加选项选择空项目
java  jna 调用DLL - 安索 - 安索的博客

(4)分别新建头文件和源文件(代码源自下文地址的博客)
java  jna 调用DLL - 安索 - 安索的博客
javaCallCpp.h代码清单

extern "C" _declspec(dllexport) void hello(); extern "C" _declspec(dllexport) int add(int first, int second);

javaCallCpp.cpp代码清单

#include "javaCallCpp.h" #include <iostream> int add(int a, int b){ return a+b; } void hello() { printf("Hello World!\n"); }


 

(5)点击完成,然后鼠标右键点击项目demo,选择生成,会发现项目报错,如下
java  jna 调用DLL - 安索 - 安索的博客
 
(6)要解决这个问题,鼠标右键点击项目demo,选择属性
java  jna 调用DLL - 安索 - 安索的博客

(7)如下图,将嵌入清单选项置为否,重新生成后,项目就顺利生成了。
java  jna 调用DLL - 安索 - 安索的博客
 
 (8)现在要找到我们生成的DLL,在demo右键选择在Windows资源管理器中打开文件夹
java  jna 调用DLL - 安索 - 安索的博客

(9)默认进入工作空间,以本机为例E:\CODE\VS2010\demo\demo,第一个demo是解决方案名,第二个demo是项目项目名,点击上一目录进入解决方案名文件夹
  java  jna 调用DLL - 安索 - 安索的博客
(10)单击文件夹下Debug,就看到我们需要的demo.dll,我们第一部分工作就算完成了

   java  jna 调用DLL - 安索 - 安索的博客


二、新建JAVA项目并调用DLL

(1)在MyEclipse中File->New->Java Project
java  jna 调用DLL - 安索 - 安索的博客

(2)project名为jna,注意选择jre为1.6,如果是1.7会报一个奇怪的错误,后面会介绍
  java  jna 调用DLL - 安索 - 安索的博客

(3)点击完成后项目右键Build Path->Configure Build Path,配置jna
java  jna 调用DLL - 安索 - 安索的博客

(4)在Libraries选项卡选择Add External JARs,然后选择你下载的jna.jar
java  jna 调用DLL - 安索 - 安索的博客

(5)将第一步生成的demo.dll放到项目目录下,可以复制dell,然后选择我们的项目jna,右键粘帖,注意要放在项目的根目录下,如下图
java  jna 调用DLL - 安索 - 安索的博客

(6)在 com.aaron.demo下新建接口JavaCallCppService.java,新建测试类Test.java
JavaCallCppService.java代码清单

package com.aaron.demo; import com.sun.jna.Library; import com.sun.jna.Native; public interface JavaCallCppService extends Library { //javaCallCpp.dll 放到工程目录下才行(与.classpath一级),原文注释写到也可以放到C:\WINDOWS\system32下,但我放到system32下运行项目,依然会报错 JavaCallCppService INSTANCE = (JavaCallCppService)Native.loadLibrary("demo", JavaCallCppService.class); public int add(int a, int b); public void hello(); }

Test.java代码清单

package com.aaron.demo; public class JavaCallCppTest { public static void main(String[] args) { System.out.println(JavaCallCppService.INSTANCE.add(1,2)); JavaCallCppService.INSTANCE.hello(); } }


(7)在JavaCallCppTest中右键Run as->Java Application,然后就可以看到控制台的结果,如果你看到如下的控制台结果,那么恭喜你!在Java平台采用jna调用DLL的环境就已经搭建成功了!
java  jna 调用DLL - 安索 - 安索的博客
 
 
 三、总结
整个过程其实比较简单,但我在完成这个过程的过程中,程序总是报错,类似如下

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'demo': ???????¨ at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:145) at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:188) at com.sun.jna.Library$Handler.<init>(Library.java:123) at com.sun.jna.Native.loadLibrary(Native.java:255) at com.sun.jna.Native.loadLibrary(Native.java:241) at com.aaron.demo.JavaCallCppService.<clinit>(JavaCallCppService.java:7) at com.aaron.demo.JavaCallCppTest.main(JavaCallCppTest.java:5)

换了几个不同博文的demo,直到最后在http://ynp.iteye.com/blog/2183118博客中,在下载的demo里面发现他采用的jre是1.6的,而我Myeclipse默认采用的jre7,终于恍然大悟。还没在网上遇到说报这个错误是因为jre引起的,这种坑爹的错,不多看几个例子真是难以发现!这也是我觉得先采用一个简单的dll文件来保证调用过程没问题,再开始调用实际用的dll的原因,因为我们得首先保证调用过程没问题,才可以开始怀疑是不是dll本身的问题。
 
----------------
主要参考博客: http://ynp.iteye.com/blog/2183118
java项目:http://vdisk.weibo.com/s/zw9HJxea93b1l
C++文件:http://vdisk.weibo.com/s/zw9HJxea93bMq
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值