关于Java调用dll的方法

2023-11-02

    Java语言本身具有跨平台性,如果通过Java调用DLL的技术方便易用,使用Java开发前台界面可以更快速,也能带来跨平台性。

    Java调用C/C++写好的DLL库时,由于基本数据类型不同、使用字节序列可能有差异,所以在参数传递过程中容易出现问题。

    使用Java调用DLL动态链接库的方案通常有三种:JNI, Jawin, Jacob. 其中JNI(Java Native Interface)是Java语言本身提供的调用本地已编译的函数库的方法,本身具有跨平台性,可以在不同的机器上调用不同的本地库。Jawin和Jacob都是sourceforge.net的开源项目,都是基于JNI技术的依赖Windows的实现,使得在Windows平台下使用COM和DLL的更加方便。

    三、JNI

    sun相关文档:http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/jniTOC.html

    JNI的完整例子 :http://www.pconline.com.cn/pcedu/empolder/gj/java/0506/642328.html

    JNI的应用方案是基于Java类和本地函数相映射的。其使用DLL的步骤还是相对比较麻烦,不但涉及到Java编程,还涉及到C/C++编程。

    JNI的使用步骤是:

    1.编写Java类,用该类将DLL对外提供的函数服务进行声明,其中的Java方法均声明为native,其方法签名可以自定义,不用实现函数体。

    2.用Javah工具将该Java类生成对应的.h头文件。

    3.最重要的比较麻烦的一步:编写C/C++代码实现.h头文件中声明的函数,该C/C++代码中包含jni.h头文件,并且编写代码时使用其中定义好的数据类型作为函数的输入和返回数据类型进行编程。用这种方法实现数据类型转换。例如数据类型:boolean(java) à jboolean(jni.h: typedef unsigned char jboolean),在自己编写的C/C++代码中使用数据类型jboolean映射Java中的boolean类型。在该步骤中,可以在C/C++代码中调用已经存在的DLL库。

    4.另外编写的Java代码时就可以使用该Java类了。

    在第3步中,编写C/C++函数时,可以使用一个叫interface pointer的env指针来调用JNI提供的一系列(很多)函数,用这些函数来访问JVM的对象和数据。

    使用JNI的缺点:使用比较麻烦,需要对已有的DLL进行封装,需要对C/C++比较了解。

    使用JNI的优点:可以跨平台调用本地库。

    四、Jawin

    官方网站:http://jawinproject.sourceforge.net/

    官方文档(Jawin介绍): http://jawinproject.sourceforge.net/jawin.html

    官方文档(Jawin使用DLL):http://jawinproject.sourceforge.net/jawinuserguide_dll.html

    官方文档(Jawin数据指令): http://jawinproject.sourceforge.net/instruction_docs.html

    Jawin的应用方案是基于函数调用时采用原始字节流传递数据的。就是在Java中指明一个DLL中的某个函数后,通过原始字节流(需要考虑参数数据类型所占的存储字节数及系统使用的字节序列)传递给该DLL函数需要的参数,其返回值也是通过原始字节流解析的方式获得正确的值。

    Jawin的使用步骤:

    1.环境配置:下载Jawin;Jawin.dll放入工程目录下;Jawin.jar相关jar文件加入到运行库中(LibPath或者Eclipse下配置工程的BuildPath-AddLibrary)。

    2.获得函数指针:new FuncPtr("DllFileName.DLL", "dllFunctionName");

    3.用LittleEndianOutputStream将函数需要的参数写入到一个原始字节流NakedByteStream。

    4.最重要的一步:调用FuncPtr.invoke()。传入参数比较复杂。

    5.解析上一步的返回值(字节数组)。

    第4步中传入的参数包括:

    1.指令字符串。一个"XXX:Y:ZZZ"格式的字符串。其含义分别是传入参数中的每个字节的数据类型意义、返回值的类型、需要从传入指针中读取的数据(inout类型参数)。比如:

    函数签名int func(int, int, struct s*, char*); //其中struct s*调用完函数后需要读出,struct s所占字节数为16。

    其指令字符串为:IIP16G:I:L4L4n16L4。该字符串在解析返回值(字节数组)时,首先应该是返回类型I对应的4个字节,然后是inout类型的参数中n16对应的16个字节。

    其中字符串的意义可以在Jawin提供的文件instructions.h中找到,或者在官方文档(Jawin数据指令)中找到常用的一些指令字符串的意义。

    2.传入参数的总字节大小。

    3.前面写好的传入参数的原始字节流。

    4.一个object数组。

    5.ReturnFlags,用以根据C/C++返回值将C/C++的错误转换为Java的异常并抛出。其中CHECK_NONE表示不检查;CHECK_FALSE和CHECK_WIN32分别表示返回0是FALSE和SUCCESS,根据是否出错决定是否抛出异常;CHECK_HRESULT表示使用COM模型中的HRESULT作为返回值,其错误码可以配置。

    使用Jawin的缺点:不方便调试,几乎所有的错误都抛出同样的异常COMException;需要对数据类型的转换比较了解;不能跨平台,对Windows的依赖性比较强。

    使用Jawin的优点:方便使用,不用进行C/C++开发,不用对原始DLL进行封装就可以方便使用。

 

    五 Jacob

    官方文档:http://danadler.com/jacob/

    Jacob是Java-Com Bridge的缩写,也可以用来调用DLL。其底层也是使用JNI实现,也具有Windows 的平台依赖性,由于网上有人反映其易用性不如jawin,所以没有深入了解。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于Java调用dll的方法 的相关文章

  • WebSphere 中跨 JVM 的会话复制

    我们建立了一个基础设施 其中网络服务器是集群的 而应用程序服务器不是 Web 服务器根据循环策略将请求路由到应用程序服务器 在这种情况下 一个应用程序服务器中可用的会话数据在另一应用程序服务器中不可用 无论如何 是否可以使来自第一个应用程序
  • 更改启动 Java 运行时后 IntelliJ IDEA 无法在 Ubuntu 上启动

    之前 我的 IntelliJ 运行得很好 但我使用的是 java 6 所以我的项目无法使用 gradle 运行 我用命令将java切换到版本8sudo update alternatives config java 我检查了java ver
  • 在 portlet 中设置 SearchContainer 以使用 EL 和 JSTL 在 JSP 中使用它

    我正在尝试使用SearchContainer在我的liferay应用程序中 目前我必须使用 JSP Scriplets 来设置results in
  • Spring安全+LocaleResolver

    我需要在身份验证成功后更改区域设置 区域设置解析器
  • Hibernate 每个子类一个表继承策略的效率

    我正在考虑 Hibernate 管理的类层次结构的表布局 当然 每个子类表技术在我看来是一般意义上最合适的 然而 通过逻辑思考 我对其性能有些担忧 尤其是随着子类数量的扩展 举一个非常简短 且经典 的示例 假设您有以下类 public ab
  • 仅使用公钥在 HD 钱包中生成以太坊地址 (bitcoinj/web3j)

    我尝试为使用 bitcoinj 库实现的 HD 钱包密钥生成以太坊地址 但我感到困惑 DeterministicSeed seed new DeterministicSeed some seed code here null 1409478
  • Grails 项目 - Servlet 调用 - ClassNotFoundException:javax.servlet.AsyncContext

    我在用 IntelliJ IDEA 终极版 12 4 grails 2 2 0 BuildConfig groovy 文件中的 grails servlet version 2 5 并实现了简单的 servlet post 请求 使用 RE
  • Glassfish 4 - JDBC 领域

    Glassfish 4 中的密码加密算法和摘要算法有什么区别 因为Password加密算法不能为空 所以我使用了MD5 Encoding使用了Hex 摘要算法为空 因此默认为 SHA 256 但是 如果我使用 JAAS 制作一个简单的登录应
  • 始终等待页面加载到 PageObjects 上

    因此 当出现问题时 我只是创建了一个简单的 selenium JBehave 代码 我将首先发布简化的代码 然后稍后解释我的问题是什么 所以这里我们有一个简单的 AbstractClass 它将在我的 PageObjects 上继承 此类仅
  • JTree ConvertValueToText 返回在更改时被截断

    我有一个自定义树实现convertValueToText 此实现取决于某些全局状态 如果返回的字符串比先前返回的字符串更长 实际上我认为更宽 因为以像素为单位触发它 则文本将被截断并用 填充 当重绘是由 取消 选择元素或某个元素引起时 情况
  • Java 客户端到服务器未知来源

    我有一个简单的乒乓球游戏 需要通过网络工作 服务器将创建一个带有球和 2 个球棒位置的游戏 当客户端连接到服务器时 服务器将创建一个名为 PongPlayerThread 的新类 它将处理客户端到服务器的输入和输出流 我的服务器工作100
  • SSLContext 初始化

    我正在看JSSE参考指南 我需要获取一个实例SSLContext为了创建一个SSLEngine 所以我可以使用它Netty以启用安全性 获取实例SSLContext I use SSLContext getInstance 我看到该方法被重
  • Java ArrayList 和 HashMap 动态

    有人可以提供一个创建Java的例子吗ArrayList and HashMap在飞行中 所以而不是做一个add or put 实际上在类实例化时为数组 哈希提供种子数据 举个例子 类似于 PHP 的例子 array array 3 1 2
  • 不使用 length() 方法的字符串长度[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 如何在不使用字符串的情况下找到字符串的长度length String类的方法 str toCharArray length应该管用 或者怎么
  • Jersey 和 Spring 中的全局异常处理?

    我正在使用 Jersey 和 Spring 3 2 以及 Open CMIS 开发 RESTful Web 服务 我没有使用 Spring 的 MVC 模式 它只是 Spring IOC 和 Jersey SpringServlet 控制器
  • SQlite 获取最近的位置(带有纬度和经度)

    我的 SQLite 数据库中存储有纬度和经度的数据 我想获取距我输入的参数最近的位置 例如我当前的位置 纬度 经度等 我知道这在 MySQL 中是可能的 并且我已经做了相当多的研究 SQLite 需要一个自定义外部函数来实现半正弦公式 计算
  • gwt 文本框添加更改处理程序

    我有一个从设计师那里收到的文本框 但是我在 GWT 中编写了操作 问题是文本框为空 但是当通过按下按钮用值填充文本框时 将显示警报框 通知值已更改 但没有成功 帮助我 TextBox zip1 null function onModuleL
  • “强制更新快照/版本” - 这是什么意思

    在 Maven 项目中 选择 更新项目 时 有一个名为 强制更新快照 版本 的选项 它有什么作用 强制更新快照 版本 就像运行以下命令 mvn U install U 也可以用作 update snapshot 看here http boo
  • 对于双核手机,availableProcessors() 返回 1

    我最近购买了一部 Moto Atrix 2 手机 当我尝试查看手机中的处理器规格时 Runtime getRuntime availableProcessors 返回 1 proc cpuinfo 也仅包含有关处理器 0 的信息 出于好奇
  • Java有没有类似微软CHESS的工具?

    是否有类似于 Microsoft 的现有 Java 工具CHESS http research microsoft com chess 或者 CHESS 源代码是否开放 以便我可以尝试将其转换为 Java 谷歌的织线工 http code

随机推荐

  • git中rejected的解决方法

    在网上搜了一下 出现这种情况的原因是因为git仓库中已经有一部分代码 所以它不允许你直接把你的代码覆盖上去 第一种解决方法是强推 即利用强覆盖方式用你本地的代码替代git仓库内的内容 git push f 第二种解决办法是先把git的东西f
  • Java面试官在面试时喜欢问哪些问题?

    作为一名技术总监 我管理的技术团队有100多人 面试的Java程序员不要太多 不同的面试官 面试的要求也不太一样 例如 有的要求表达好 会沟通 有的要求技术好 能直接上手撸代码 搞项目 有的要求人踏实 稍微带一带 能干活就行 有的要求 我的
  • 轮播图禁用手势滑动

    要禁用手势滑动 并只允许自动轮播 你可以使用autoplayDisableOnInteraction属性来实现 以下是如何在Flutter中使用flutter swiper插件进行配置 首先 在pubspec yaml文件中添加flutte
  • 03 开始使用openEuler操作系统

    文章目录 03 开始使用openEuler操作系统 3 1 目标 3 2 Linux以及openEuler中的GUI与CLI 3 3 Linux的两种登录方式 3 3 1 本地登录 3 3 2 远程登陆 3 4 退出登录 注销 3 5 op
  • 【Markdown语法高级】 让你的博客更精彩(三:常用图标模板)

    引言 铭记于心 我唯一知道的 便是我一无所知 概述 众所周知 Markdown是一种轻量级标记语言 创始人为约翰 格鲁伯 英语 John Gruber 它允许人们使用易读易写的纯文本格式编写文档 然后转换成有效的XHTML 或者HTML 文
  • 【工作经验】基于Vue2,element ui,vue-cli,vuex,vue-router,axios,echarts,markdown-loader并结合个人前端学习笔记的vue前端框架实例

    demo目的 vue是目前主要的前端框架 虽然目前网页制作通常以前后端分离的形式 然而前端知识不止是前端工程师需要掌握 后端工程师 数据工程师 数据分析师都有必要有所了解 本demo旨在记录个人前端学习中的笔记以及学习网页前端主流vue框架
  • SpringSecurity创建角色和设置权限

    一 创建角色在之前创建完项目后 可以在SpringSecurityConfig类中重写configure方法并进行自定义创建角色 public class SpringSecurityConfig extends WebSecurityCo
  • git push fatal: 不能读commit id 问题

    现象 git merge分支的时候无冲突 git push提示一下报错 fatal 不能读 fdc91c997bd43dddd3eb84094e79b5a681453475 error 远程解包失败 eof before pack head
  • python文件夹之间的调用

    1 同一目录下的调用 incoke py def add a b print a b main py from incoke import add add 5 6 import incoke是调用整个文件夹 from incoke impo
  • python中的异常

    目录 一 常见的几种异常 二 异常的处理 异常就是指程序出错 我们平常所说的报错了就是程序出现异常 一 常见的几种异常 1 NameError 指变量未定义 系统识别不到出错的变量名 2 ValueError 要求输入一个整数 input
  • Java程序设计——execute()与executeUpdate()(JDBC编程)

    目录 一 execute 二 executeUpdate 一 execute execute 几乎可以执行任何SQL语句 返回值是boolean值 表明该SQL语句是否返回ResultSet对象 boolean值 true 使用getRes
  • 想知道百度云AI智能小助手有哪些黑科技?测评来给你揭秘!

    一个好消息 之前申请的百度云 云一朵 智能助理已经通过啦 还挺快的 用了一下 感觉不错哎 打开百度网盘就可以看到右上角的 云一朵智能助理 可以直接点开使用 在对话框有提示 可以输入 也可以来发出指令 只要你输入就会提示你它有啥功能 比如你可
  • R与SPSS、SAS相比较_Python 在数据分析工作中的地位与R语言、SAS、SPSS 比较如何?

    转自 http m elecfans com article 611407 html 统计分析的软件和程序分析 能够用来做统计分析的软件和程序很多 目前应用比较广泛的包括 SPSS SAS R语言 Matlab S PLUS S Miner
  • MMsegmentation教程 6: 自定义运行设定

    自定义优化设定 自定义 PyTorch 支持的优化器 我们已经支持 PyTorch 自带的所有优化器 唯一需要修改的地方是在配置文件里的 optimizer 域里面 例如 如果您想使用 ADAM 注意如下操作可能会让模型表现下降 可以使用如
  • sqlserver的sp_addlinkedserver在存储过程中的使用问题

    sp addlinkedserver是sqlserver中用于跨数据库操作 该函数用于创建一个连接 在开发中遇到业务需求 需要创建一个存储过程 在里面做跨数据库操作 该存储过程创建语句如下 创建存储过程begin if object id
  • Appium自动化测试基础 — APPium基本原理

    1 APPium自动化测试架构 APPium是一个C S架构的自动化测试框架 APPium的核心其实是一个暴露了一系列REST API的server 也就是Appium的核心是一个提供了一组REST API的Web服务器 这个server的
  • 区块链专家洪蜀宁:实现全民普惠的专业化产品设计

    洪蜀宁老师 曾两次受邀在混沌大学授课 毕业于清华大学计算机系 曾长期在中国人民银行工作 对金融科技有着丰富的研究和实战经验 洪蜀宁早在十年前 2011年 就发表了国内第一篇研究比特币的论文 比特币 一种新型货币对金融体系的挑战 该文刊登于
  • CSS之文字样式

    1 字体类型设置 标签名 font family 注意 英文字体只适用于英文 中文字体可以适用中文和英文 代码
  • linux命令总结【系统,防火墙,java,文件及文件夹,解压缩,mysql,nginx,redis,rabbitmq,rocketmq,elasticsearch,nacos,canal】

    日常开发过程中需要用到linux相关命令 整合一下 如发现问题欢迎留言反馈 目录 一 系统相关命令 二 防火墙 三 java相关 1 安装 2 启动jar包 3 java进程 四 文件及文件夹 1 上传下载文件 2 解压文件 3 查看文件
  • 关于Java调用dll的方法

    Java语言本身具有跨平台性 如果通过Java调用DLL的技术方便易用 使用Java开发前台界面可以更快速 也能带来跨平台性 Java调用C C 写好的DLL库时 由于基本数据类型不同 使用字节序列可能有差异 所以在参数传递过程中容易出现问