关于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的方法 的相关文章

  • 存根方法时出现 InvalidUseOfMatchersException

    我有这个 TestNG 测试方法代码 InjectMocks private FilmeService filmeService new FilmeServiceImpl Mock private FilmeDAO filmeDao Bef
  • 打印星号的 ASCII 菱形

    我的程序打印出这样的钻石 但只有当参数或菱形的每一面为4 例如如果我输入6 底部三角形的间距是错误的 我一直在试图找出答案 当参数改变时 底部的三角形不会改变 只有顶部的三角形会改变 它只适用于输入4 public static void
  • GWT - 如何组织项目以拥有多个网页以及它们之间的导航

    我是 GET 的新手 顺便说一句 它给我留下了深刻的印象 并且发现它对于像我这样熟悉 C NET 桌面技术并愿意编写 Web 应用程序的人来说非常有吸引力 我根据 GWT Eclipse 向导生成的示例启动了自己的项目 该项目生成带有面板的
  • 通往楼梯顶部的可能路径

    这是一个非常经典的问题 我听说谷歌在他们的面试中使用过这个问题 问题 制定一个递归方法 打印从楼梯底部到楼梯顶部的所有可能的独特路径 有 n 个楼梯 您一次只能走 1 步或 2 步 示例输出 如果它是一个有 3 级楼梯的楼梯 1 1 1 2
  • 需要使用 joda 进行灵活的日期时间转换

    我想使用 joda 解析电子邮件中的日期时间字符串 不幸的是我得到了各种不同的格式 例如 Wed 19 Jan 2011 12 52 31 0600 Wed 19 Jan 2011 10 15 34 0800 PST Wed 19 Jan
  • Jackson XML ArrayList 输出具有两个包装器元素

    我在 Jackson 生成的 XML 输出中得到了两个包装器元素 我只想拥有一个 我有一个 Java bean Entity Table name CITIES JacksonXmlRootElement localName City pu
  • 使用 Guice 优化注册表

    你好 今天思考了一种优化 有一些疑问 语境 我正在使用 Guice 2 进行 Java 开发 在我的网络应用程序中 我有一个转换器注册表 可以即时转换为某种类型 转换器描述如下 public class StringToBoolean im
  • 从 GitHub 上托管的 Spring Cloud Config Server 访问存储库的身份验证问题

    我在 GitHub 上的存储库中托管配置 如果我将回购公开 一切都好 但如果我将其设为私有 我将面临 org eclipse jgit errors TransportException https github com my user m
  • 内部存储的安全性如何?

    我需要的 对于 Android 我需要永久保存数据 但也能够编辑 并且显然是读取 它 用户不应访问此数据 它可以包含诸如高分之类的内容 用户不得对其进行编辑 我的问题 我会 并且已经 使用过Internal Storage 但我不确定它实际
  • 使用 Mockito 模拟某些方法,但不模拟其他方法

    有没有办法使用 Mockito 模拟类中的某些方法 而不模拟其他方法 例如 在这个 诚然是人为的 Stock我想嘲笑的班级getPrice and getQuantity 返回值 如下面的测试片段所示 但我想要getValue 执行乘法 如
  • 流中的非终结符 forEach() ?

    有时 在处理 Java Stream 时 我发现自己需要一个非终端 forEach 来触发副作用但不终止处理 我怀疑我可以用 map item gt f item 之类的方法来做到这一点 其中方法 f 执行副作用并将项目返回到流中 但这似乎
  • java库维护数据库结构

    我的应用程序一直在开发 所以偶尔 当版本升级时 需要创建 更改 删除一些表 修改一些数据等 通常需要执行一些sql代码 是否有一个 Java 库可用于使我的数据库结构保持最新 通过分析类似 db structure version 信息并执
  • 返回 Java 8 中的通用函数接口

    我想写一种函数工厂 它应该是一个函数 以不同的策略作为参数调用一次 它应该返回一个函数 该函数根据参数选择其中一种策略 该参数将由谓词实现 嗯 最好看看condition3为了更好的理解 问题是 它没有编译 我认为因为编译器无法弄清楚函数式
  • 是否可以使用 Java Guava 将函数应用于集合?

    我想使用 Guava 将函数应用于集合 地图等 基本上 我需要调整 a 的行和列的大小Table分别使所有行和列的大小相同 执行如下操作 Table
  • Java Swing:需要一个高质量的带有复选框的开发 JTree

    我一直在寻找一个 Tree 实现 其中包含复选框 其中 当您选择一个节点时 树中的所有后继节点都会被自动选择 当您取消选择一个节点时 树中其所有后继节点都会自动取消选择 当已经选择了父节点 并且从其后继之一中删除了选择时 节点颜色将发生变化
  • Hamcrest Matchers - 断言列表类型

    问题 我目前正在尝试使用 Hamcrest Matchers 来断言返回的列表类型是特定类型 例如 假设我的服务调用返回以下列表 List
  • org.apache.commons.net.io.CopyStreamException:复制时捕获 IOException

    我正在尝试使用以下方法中的代码将在我的服务器中创建的一些文件复制到 FTP 但奇怪的是我随机地低于错误 我无法弄清楚发生了什么 Exception org apache commons net io CopyStreamException
  • 在浏览器刷新中刷新检票面板

    我正在开发一个付费角色系统 一旦用户刷新浏览器 我就需要刷新该页面中可用的统计信息 统计信息应该从数据库中获取并显示 但现在它不能正常工作 因为在页面刷新中 java代码不会被调用 而是使用以前的数据加载缓存的页面 我尝试添加以下代码来修复
  • 洪水填充优化:尝试使用队列

    我正在尝试创建一种填充方法 该方法采用用户指定的初始坐标 检查字符 然后根据需要更改它 这样做之后 它会检查相邻的方块并重复该过程 经过一番研究 我遇到了洪水填充算法并尝试了该算法 它可以工作 但无法满足我对 250 x 250 个字符的数
  • Spring表单ModelAttribute字段验证避免400 Bad Request错误

    我有一个ArticleFormModel包含正常发送的数据html form由 Spring 使用注入 ModelAttribute注释 即 RequestMapping value edit method RequestMethod PO

随机推荐

  • 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库时 由于基本数据类型不同 使用字节序列可能有差异 所以在参数传递过程中容易出现问