java调用dll文件,java用jna调用dll,visual studio 工具封装c++ 函数为dll动态库(史上最详细,续更)

前述:

  • 本帖为lz原创,经过实际运行,欢迎转载注明出处。
  • 此帖相对比较长,但是十分详细。lz花了将近两天的时候研究JNA调用dll的过程,写这篇帖子花了将近6个小时,所以如果你花了一天的时间让程序成功运行那说明你赚了。在给各位提供方便的同时也请尊重lz的劳动,转发注明出处,谢谢!(楼主基本每天都会在线,有不足之处欢迎指出,提的问题看到后马上回复)
  • DLL动态库是在Windows环境运行的,后期会加上调用Linux系统中的SO

大概步骤:

  • 安装MingW,为c++提供运行环境
    MinGW 就是 GCC 的 Windows 版本 ,而gcc呢是GNU编译器套件(GNU Compiler Collection),它包括了C、C++等等的前端也包括了这些语言的库,我们需要使用c++所以需要安装,不清楚c++的可以进此帖查看:查看

  • 安装Microsoft Visual Studio 2017 将c++文件编译生成DLL文件
    实际上安装这款软件我也不是很情愿的,将近有4个G的大小,因此我一开始尝试使用Idea生成DLL文件(我上一篇帖子就是如此,是通过JNI生成),没有成功,步骤很繁琐,而且很多过程不可控,所以选择了专业的软件。不使用工具其实就相当于使用用记事本编写web项目,所以还是要安装

  • 通过Java调用dll中的对应方法
    我们只需通过引入JNA的jar包然后通过简单的配置,就可以实现调用dll中的方法


接下来我们开始入坑之旅吧
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓


关于JNA,与JNI的比较:

有过跨语言、跨平台开发的程序员都知道,跨平台、语言调用的难点,就是不同语言之间数据类型不一致造成的问题。绝大部分跨平台调用的失败,都是这个问题造成的。关于这一点,不论何种语言,何种技术方案,都无法解决这个问题。JNA也不例外。

上面说到接口中使用的函数必须与链接库中的函数原型保持一致,这是JNA甚至所有跨平台调用的难点,因为C/C++的类型与Java的类型是不一样的,你必须转换类型让它们保持一致,比如printf函数在C中的原型为:

void printf(const char *format, [argument]);

你不可能在Java中也这么写,Java中是没有char *指针类型的,因此const char *转到Java下就是String类型了。

这就是类型映射(Type Mappings),JNA官方给出的默认类型映射表如下:
在这里插入图片描述

还有很多其它的类型映射,需要的请到JNA官网查看。

另外,JNA还支持类型映射定制,比如有的Java中可能找不到对应的类型(在Windows API中可能会有很多类型,在Java中找不到其对应的类型),JNA中TypeMapper类和相关的接口就提供了这样的功能。

JNA能否替代JNI
这可能是大家比较关心的问题,但是遗憾的是,JNA是不能完全替代JNI的,因为有些需求还是必须求助于JNI。

使用JNI技术,不仅可以实现Java访问C函数,也可以实现C语言调用Java代码。

而JNA只能实现Java访问C函数,作为一个Java框架,自然不能实现C语言调用Java代码。此时,你还是需要使用JNI技术。

JNI是JNA的基础,是Java和C互操作的技术基础。有时候,你必须回归到基础上来。

引用自:查看


安装MingW


  • 首先我们需要去官网下载压缩包,下载Windows版本32位和64位都适用的文件,下载查看
    在这里插入图片描述
  • 再安装文件,基本不用操作,点击下一步就行,安装步骤推荐链接查看
    备注:lz在安装的时候遇到这么样一个问题:在为mingw配置环境变量MinGW_HOME时,将值设置为mingw的安装目录下(bin目录的上一层)时会出现在其他路径运行gcc指令失效的问题,但也有不是每次都无效。最后lz直接将MinGW_HOME的值配置到bin目录下,在path中添加对应%MinGW_HOME%就没出现此问题。跟大家分享一下,希望大家不会出现这样的问题。在这里插入图片描述
    在这里插入图片描述最后在任意路径下运行gcc - v指令不报错就代表安装完成,如下图:
    在这里插入图片描述

安装Microsoft Visual Studio 2017 将c++文件编译生成DLL文件


  • lz建议安装较高版本的Microsoft Visual Studio,我使用的是2017版本的,低版本存在一些问题,会导致你安装失败后需要重新安装,而且新版本支持模块化安装

  • 下载Microsoft Visual Studio 2017地址https://docs.microsoft.com/zh-cn/visualstudio/productinfo/vs2017-system-requirements-vs
    在这里插入图片描述

  • 下载完成对Microsoft Visual Studio 2017 进行解压安装,安装步骤推荐链接https://www.sohu.com/a/258291421_468739

    注意当安装到选择功能模块这个界面时,由于我们是用来制作dll,所以只需勾选最前面三个Windows和单独的WINDOWS 8.1 SDK(一定要勾选一定一定!)
    其余按照安装步骤安装即可。
    在这里插入图片描述

  • 提示安装完成之后去发现桌面没有快捷方式,可以这样查找:WIN+Q快捷操作出现搜索框,输入deven差不多就可以出来了,如下图;(若快捷键不生效可在安装目录\Common7\IDE\devenv.exe,例如楼主的就是D:\Visual Studio 2017\Common7\IDE路径,如下图)
    在这里插入图片描述
    运行程序的exe程序位置
    在这里插入图片描述
    ===========================================================================================

使用Visual Studio 2017生成DLL过程

  • 操作过程根据哔哩哔哩网站中搜索:VC《VC++动态库DLL与静态库LIB编程》视频下的第二节部分入口点函数机器导出函数的讲解操作,可以直接观看此视频(视频使用的是2008版本操作过程有些许不同)链接:查看视频
    步骤:

1.打开Visual Studio 2017软件
2.点击左上角 文件》新建》项目后进入选择页面(无法截图)
3.桌面平台》动态链接库
在这里插入图片描述生成的项目层级关系
在这里插入图片描述
4.添加导出def文件 源文件》添加》新建项》模块定义文件
在这里插入图片描述
5.对def文件进行编辑,如图片所示
代码:

LIBRARY "WindowsProject2"
EXPORTS
 add @1

在这里插入图片描述
6.实现第五步中的add函数,源文件》添加》新项目》C++文件
在这里插入图片描述
7.编辑cpp文件,简单实现add方法,解释如图:
代码:

#include "stdafx.h"
int add(int a, int b) {
	return a + b;
}

在这里插入图片描述
8.为生成dll做准备,统一jdk和生成的dll位数,仔细看一定要设置:不然调用的时候会因为生成的dll为32位而jdk64位报错

  • 选中项目》右键》属性 将“配置(c)”设置为Release ,平台(p)设置为×64,如图

在这里插入图片描述

  • 正常情况刚安装的软件没有×64的选项,可跟着我一起添加:添加×64平台
    点击前面打开的平台页面右侧的配置管理器,选择平台出,点击新建,再点击下拉框中的×64即可

    在这里插入图片描述

    • 添加×64

    在这里插入图片描述9.上面操作完成后将第八步的配置设置为Release,平台设置为×64
    10.生成dll文件,选中项目,右键出现的重新生成,即可生成对应的dll文件,如下如所示则代表生成成功
    在这里插入图片描述
    备注:如果生成的时候出现了error MSB803找不到8.1的SDK包(如下图)的错误,则说明你在安装软件的时候没有按照我的提示添加sdk8.1包,解决方案按照此链接操作再次运行即可解决问题,链接:查看
    在这里插入图片描述
    11.查找生成的dll文件,64位生成的dll文件位置如下图,会在控制台打印出来
    在这里插入图片描述

32位的可直接选中项目右键倒数第二个在资源文件中打开文件夹,然后上一层目录,进入debug中就有对应生成的dll文件


通过java代码调用方法

  • 引入jna的jar包,可以在pom文件中引入,也可以直接导入jar文件
    在这里插入图片描述
  • 创建一个interface 继承Library接口,在接口中声明方法,并且加载对应的dll文件,如图
    代码:
public interface DLL extends Library {
//JNA加载
    DLL instance = (DLL) Native.loadLibrary("DLLTest", DLL.class);

    int add(int a, int b);
}

说明:实际上有多种方式加载dll文件,**JNI中(本文为JNA调用)**也可以通过System.load()和System.loadLibrary()加载dll文件,前者需要写dll的绝对路径,后者只需要写dll的名称即可,具体区别可以查看此链接:查看
在这里插入图片描述dll路径查找设置
-Djna.library.path=*** 后面的路径值通过点击项目中dll文件copy path获得,就是dll文件在系统中的路径,我将DLLTest.dll文件放在owntest项目的lib目录下,所以看到的路径就如图
在这里插入图片描述

  • 设置完成之后创建一个main方法调用add方法,执行成功,如下图(由于楼主在创建项目的时候选为exe程序,故没有成功生成dll文件,在创建项目的时候必须选择动态链接库dll,否则生成的就是一个exe的程序)
    在这里插入图片描述



最后总结下在执行时可能出现的问题

1.java.lang.UnsatisfiedLinkError异常,如下,一堆乱七八糟的文字,如下

java.lang.UnsatisfiedLinkError: Unable to load library 'Dll1': ÕҲ»µ½ָ¶¨

此异常为lz操作时已经着重讲过的问题,就是在生成dll文件时没有统一jdk和vc 2017工具打包的位数,需要相同,要不全是32位要不全是64位,解决此异常需要将生成dll的第8步开始重新生成一遍dll

2.如果按照上面步骤后依旧出现此问题,则可这样操作:

-Djna.library.path=D:\AppClass\owntest\lib

在这里插入图片描述
在这里插入图片描述
目前只出现了这个问题
至此结束,感谢观看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一米阳光zw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值