Java调用动态库最简便方法和最好用的组件

Java调用动态库最简便方法和最好用的组件
记得以前 Java 要调用C/C++写得动态库都是用的 JNI 方式,还需要自己写不少 C/C++ 代码。比如说要在Java中调用已有的动态库,如 Windows 的 user32.dll 的方法 MessageBoxA,具体步骤是 Java 中声明一个 native 方法,然后用 javah 命令生成JNI样式的头文件,再自己实现头文件中声明的方法,在实现方法中装载动态库 user32.dll,调用 MessageBoxA 方法,需要把自己写的这部分 C/C++ 代码封装成一个动态库,如Sample.dll,最后在 java 中装载 Sample.dll,然后执行其中所声明的本地方法。

可见,用老实的JNI方式,我们在调用一个已知动态库的时候还需要额外生成一个符合JNI规则的动态库作为桥梁,显得有点多余了。

下面我将引入一个开源的组件 JNative,在 http://sourceforge.net/projects/jnative 下载(我是通过在sourceforge中输入java dll搜索到的),通过它调用已有动态库中的方法就非常的方便,因为中间的JNI处理过程它都为我们做好了。JNative 现在还是 Beta1 版,期待正式版的出炉,还不知道这个版本将会有什么Bug出现。

我们下载到的 jnative 的目录中可以看到三个文件,分别是 JNative.dll,libjnative.so,JNative.jar

JNative.dll 为 Windows 平台下用的,可以拷到相应的lib加载路径,如user.dir、path、system32或windows目录下
libnative.so 为Linux平台下用的,可以拷到相应的lib加载路径,如user.dir、path目录下
JNative.jar 这个就是我们编程时候要用的

在下载的 jnative 的源代码中有示例代码,观看代码 org\xvolks\test\JNativeTester.java 就知道 jnative 是如何调用动态库方法的

如代码行 User32.messageBox(0, "Demonstrates JNative in action with many Win32 calls", "Welcome to JNative", 0);

是调用的关User32的messageBox方法,而messageBox的代码是

public static final int messageBox( int parentHandle, String message,
String caption, int buttons) throws NativeException,
IllegalAccessException {
JNative n = null ;
try {
n = new JNative(DLL_NAME, "MessageBoxA" ); // 常量DLL_NAME的值为User32.dll
// 构造JNative时完成装载User32.dll,并且定位MessageBoxA方法
n.setRetVal(Type.INT); // 指定返回参数的类型
int i = 0 ;
n.setParameter(i++, Type.INT, "" + parentHandle);
n.setParameter(i++, Type.STRING, message);
n.setParameter(i++, Type.STRING, caption);
n.setParameter(i++, Type.INT, "" + buttons); // 指定位置上的参数类型和值
n.invoke(); // 调用方法
return Integer.parseInt(n.getRetVal());
} finally {
if (n != null )
n.dispose(); // 记得释放
}
}

上面的注释是我加上去的。
Type有一种叫做Type.PSTRUCT枚举值,对C/C++中结构的处理都考虑到了,只要用JNative的Pointer类的实例来与结构对应就行了。org\xvolks\test\SNDPTester.java中演示了如何传递C/C++中的结构相对应的Java数据类型,也就是怎么封装成一个JNative的Pointer类型。

还有在JNative中用了JDK1.5的一些特性,如枚举、静态引入等,所以在JDK1.4下是不能用的。

附:JNative 当前版本到了 1.3.2 了


--------------------------------------------------------------------------------
[版权声明]本站内文章,如未标注 [转载],均系原创或翻译之作,本人 Unmi 保留一切权利。本站原创及译作未经本人许可,不得用于商业用途及传统媒体。网络媒体可随意转载,或以此为基础进行演译,但务必以链接形式注明原始出处和作者信息,否则属于侵权行为。另对本站转载他处文章,俱有说明,如有侵权请联系本人,本人将会在第一时间删除侵权文章。及此说明,重之之重。
posted on 2006-05-18 02:09 隔叶黄莺 阅读(746) 评论(15) 编辑 收藏



Feedback
# re: Java调用动态库最简便方法和最好用的组件 2007-11-14 10:31 啥事
有没有如何获得dll传出参数的例子 回复 更多评论



# re: Java调用动态库最简便方法和最好用的组件 2007-11-14 12:37 隔叶黄莺
没有这么聪明,C++也没办法知道,只能按照API约定来调用传参取值,知道一个地址不标识是什么类型的 回复 更多评论



# re: Java调用动态库最简便方法和最好用的组件 2007-11-18 10:09 隔叶黄莺
JNative 的 getRetVal() 方法就是获取dll中函数传出的参数。 回复 更多评论



# re: Java调用动态库最简便方法和最好用的组件 2007-11-22 17:34 啥事
可能是我没有表述清楚,我想知道jnative如何调用dll的出参。
getRetVal()只是调用是否成功的一个返回值。如:
我们有个HNBridge.dll中有getParam(Long pDataHandle,String paramName,REF String paramValue,UINT nMaxValuseLenth) 其中REF String paramValue
是一个返回值,getRetVal()只是校验该函数调用是否成功。
java如何调用REF String paramValue。
这是我的源码
public static final Object[] getparam(long s1,String s2,long s4 ) throws NativeException,IllegalAccessException{
JNative n=null;
try{
n= new JNative("HNBridge.dll", "GetParam");
n.setRetVal(Type.INT);
// n.setMemory(0, "");
//n.set
int i=0;
Pointer s6 = new Pointer(MemoryBlockFactory.createMemoryBlock(1024));
s6.zeroMemory();
s6.setStringAt(0, "ddd");
use=new UserCall("");
// s6.setStringAt(0, "sss");
//pTar=new Pointer(MemoryBlockFactory.createMemoryBlock(36));
n.setParameter(i++, Type.LONG, ""+s1);
n.setParameter(i++, Type.STRING,s2);
// n.setParameter(i++, use.createPointer());
n.setParameter(i++, s6);
n.setParameter(i++, Type.LONG, ""+s4);
n.invoke(); // 调用方法
//System.out.println(n.getParameter(0));
// s3=s6.getAsString();
System.out.println(s6.getAsString()+"fhz");
Object [] mm=new Object[2];
mm[0]=n.getRetVal();
// mm[1]=use.getValueFromPointer();
mm[1]=s6.getAsString();
// mm[1]=s3;
//use.dispose();
return mm;

}

但总是得不到正确值
回复 更多评论



# re: Java调用动态库最简便方法和最好用的组件 2007-11-22 17:40 隔叶黄莺
getRetVal()是实际的返回值 回复 更多评论



# re: Java调用动态库最简便方法和最好用的组件 2007-12-10 17:37 hill
为什么我用自己写的程序老是收到这样的错误
Exception in thread "main" java.lang.IllegalStateException: JNative library not loaded, sorry !
at org.xvolks.jnative.JNative.<init>(JNative.java:337)
at org.xvolks.jnative.JNative.<init>(JNative.java:269)
at test.TestJNI.main(TestJNI.java:30)
即使是用JNativeTester.java也会收到错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.xvolks.jnative.JNative.nLoadLibrary(Ljava/lang/String;Ljava/lang/String;Z)I
at org.xvolks.jnative.JNative.nLoadLibrary(Native Method)
at org.xvolks.jnative.JNative.<init>(JNative.java:348)
at org.xvolks.jnative.JNative.<init>(JNative.java:269)
at org.xvolks.jnative.util.User32.MessageBox(User32.java:396)
at test.JNativeTester.main(JNativeTester.java:312)
回复 更多评论



# re: Java调用动态库最简便方法和最好用的组件 2007-12-10 17:42 hill
用JNativeTester.java去load “user32.dll"会出现上面的错误,但是load自己的dll却是Exception in thread "main" java.lang.UnsatisfiedLinkError: D:\Project\test\src\test\umenable.dll: Can't find dependent libraries
?难道我的dll是不能用的? 回复 更多评论



# re: Java调用动态库最简便方法和最好用的组件 2007-12-10 17:43 隔叶黄莺
把JNative.dll 为 Windows 平台下用的,可以拷到相应的lib加载路径,如user.dir、path、system32或windows目录下,保证你的java程序能加载到这个动态库 回复 更多评论



# 还是有问题 2007-12-11 12:38 hill
谢谢你的解答,现在可以load我的dll了不过问题又来了,我发现看不到dll里面的方法,即使用JNative的getDLLFileExports返回的都是(几个dll都是返回这样的)
DllCanUnloadNow
DllGetClassObject
DllRegisterServer
DllUnregisterServer
我的这些dll好像是基于com的,不多我对这些都不熟悉,咋办? 回复 更多评论



# re: Java调用动态库最简便方法和最好用的组件 2007-12-11 12:48 隔叶黄莺
基于Com的,有些不一样的。Com初始化过程在哪里完成的呢 回复 更多评论



# re: Java调用动态库最简便方法和最好用的组件 2007-12-12 10:50 hill
谢谢你的解答,我发现我这个程序用jacob(Java-Com Bridge)来做就可以了,非常简单,只要new一个ActiveXComponent,就可以调用里面的函数了 回复 更多评论



# re: Java调用动态库最简便方法和最好用的组件 2008-04-30 10:18 cary
我用JNative来调用DLL但是现在遇到问题是类型间的转换,DLL里的类型始终不能被JAVA认出来。那怕我在DLL里这样写:return "hello",java里:
n3.setRetVal(Type.STRING);
System.out.println(n3.getRetVal())
都不能被打印出来,不知道你有遇到过类型方面的问题吗? 回复 更多评论



# re: Java调用动态库最简便方法和最好用的组件 2008-04-30 10:32 隔叶黄莺
没遇到这种问题,请把你能重现问题的完整代码贴出来看看 回复 更多评论



# re: Java调用动态库最简便方法和最好用的组件 2008-04-30 12:51 cary
n3=new JNative("CID_test","CID_GetNum");
n3.setRetVal(Type.STRING);
System.out.println("n3=="+n3.getRetVal());
这是JAVA代码。
c++

extern "C" _declspec(dllexport) string CID_GetNum()
{
char buf[32];
string s;
int i=0;
i=SW_ReceiveCID(0,buf);
if(i!=0)
{
s += buf;
return "hello";
}
return "hello";
}
你看看我这样写有问题吗?
@隔叶黄莺
回复 更多评论



# re: Java调用动态库最简便方法和最好用的组件 2008-04-30 21:06 隔叶黄莺
尽量能的话还是严谨一点吧
_declspec(dllexport) 前面是两个下划线,你少写了一个
你用 string 也该把 string.h 或 string #include 进来
SW_ReceiveCID 不存在的函数


存在两个问题
1. 你的动态库必须返回一个 c-style 字符串,如 char*,用 std 的 string,java 那边不会认成是 String,你可以中间过程用 string,最后返回的字符串要是 c-style 格式。这应该不成问题,你见过许多 windows api 就是用的这种字符串,如 LPSTR 样的

2. 你在 java 代码忘了调用 dll 的相应方法,在取返回值之前必须 n3.invoke() 一下。

重新试试吧,祝你好运
Java通过JNA或JNI调用C++动态库 阅读详情

相关推荐

java 自动按键精灵程序

java 自动按键精灵程序,通过读取XML文件来完成,界面简单,易操作,并且付有说明书,能对像windows优化大师的未注册用户,校内网的开心农场的自动收获农作物等,

java 操作 User32 的一次小尝试

最近看到同学用C#写了一个连连看的破解小程序,顿时羡慕万分。 后面翻阅资料的时候发现了java 居然也可以操作桌面系统。 但是其中确遇到了很多的问题,这里记录一下。 首先 项目刚开始就遇到了问题,利用jna jar包 中的user32 获取屏幕窗口 方法如下 首先创建一个接口类 User32 // 提供 获取窗口句柄 获取窗口矩形坐标 鼠标控制 public interface User32...

QFann的博客 5000

Java调用dll实例

Java调用dll实例,这里包含了jacob+jawin+jna+jnative方法在内的各种资源以及demo,有许多都是优快云中的下载资源。由于本人也是新手,为了下载关于调用dll的相关资源消耗了大量积分,特此将手中资源进行汇总,为了方便大家。这2分一定会让大家物有所值。

Java调用操作系统API与DLL的使用

       之前一直觉得Java不能调用系统API就是一个莫大的遗憾,后来发现,我错了,还真可以的,下面就由小强带你研究研究,如果你会会C++当然最好,学习Java的都知道,Java是跨平台的语言,需要虚拟机,Java是无法直接访问操作系统API的,这样在某些需求下就会受到限制,比如。我现在想关闭显示器,或锁定鼠标键盘,或获取系统信息,获取浏览器URL,获取播放器来播放多媒体等等,我们会发

Code菜鸟的专栏 7238

JNA调用DLL简单示例

JNA调用DLL简单示例,应该很容易看的懂的。

双向全桥隔离dc-dc变换器(DAB)

在全功率范围内,零电压开通优化调制方法能够实现双向全桥隔离dc-dc变换器所有开关的零电压开通,来提升变换器的效率,但其调制模式不连续。当变换器两端电压不匹配时,变换器的电流应力和回流功率将增加,软开关范围将变窄,变换器的效率显著降低。在轻载时,这两种电流优化调制方法采用相同的调制模式;在重载时,最小电流有效值调制方法具有两种调制模式,而最小电流应力调制方法只有一种。双向全桥隔离dc-dc变换器(DAB)和Buck/Boost不同,该变换器通过交流电感进行功率传输,其调制和控制不适合直接借鉴已有的研究。

m0_59329334的博客 3532

java user32.dll_User32.java

");getProcessHandle.setRetVal(Type.INT);nBufferGWT = new Pointer(MemoryBlockFactory.createMemoryBlock(4));getProcessHandle.setParameter(0, hwnd.getValue());getProcessHandle.setParameter(1, nBufferGWT)...

weixin_29119033的博客 415

【Stata双重差分模型】双重差分DID的具体操作步骤

本案例将详细阐述如何使用双重差分法进行实证分析,并展示具体的STATA操作代码。

a519573917的博客 2万+

java 调用user32.dll 锁定电脑

public interface Kernel32 extends Library { public boolean Beep(int FREQUENCY, int DURATION); public void Sleep(int DURATION); } public interface User32 extends Library { boolean LockWorkStati

ilyysys的专栏 2191

MaixCAM2 4K AI相机硬件解析与开发实战

嵌入式AI视觉开发中,边缘计算设备的选择直接影响项目落地效果。以NPU为核心的AI加速技术通过专用指令集优化,可在低功耗下实现10+TOPS算力,典型应用包括工业质检、智能门禁等实时场景。MaixCAM2作为新一代4K AI相机,搭载AX630 SoC芯片,其双核Cortex-A53与NPU的异构架构,在运行YOLOv11n模型时可达113FPS,显著优于传统方案。开发时需注意模型量化部署技巧,如INT8量化需500+张校准图片覆盖多光照条件,避免准确率下降。设备扩展性方面,PMOD接口支持热成像、ToF传

weixin_30819085的博客 690

【任何电机可使用的七段式s曲线-----包括matlab代码和simulink仿真】

S形加加速(T1)→>匀加速(T2)→减加速(T3)→>匀速(T4 )>加减速(T5)>匀减速(T6)-→>减减速(T7)

weixin_44312889的博客 6309

java调用user32的API_Java后台调用API的方法

Java后台调用API的方法其实API接口就相当于一个方法或者函数,只不过通过http来访问。API接口也需要参数,也会返回结果。调用接口的步骤:(一)客户端请求接口的URL。(二)传入接口需要的参数param。(三)接口返回调用的结果(数据)。(四)客户端解析结果。.需要自己创建一个HttpUtil类。下面以自己创建的HttpUtil为例。HttpUtil类一般包括:doGet和doPost方法...

weixin_39687189的博客 608

28-基于STM32单片机的便携式健康监测系统设计与实现(程序+原理图+元件清单)

本文详细介绍了基于STM32单片机的便携式健康监测系统设计与实现,该系统集成MAX30102光电传感器和MSP20压力传感器,实时监测心率、血氧和血压等关键生理指标。通过STM32F103C8T6主控芯片和HC-05蓝牙模块,实现数据采集、处理及无线传输,具有便携性高、操作简便等特点,适用于家庭健康监护和户外运动场景。

weixin_29191669的博客 420

Java调用动态库(dll)最简便方法和最好用的组件

记得以前 Java 要调用C/C++写得动态库都是用的 JNI 方式,还需要自己写不少 C/C++ 代码。比如说要在Java中调用已有的动态库,如 Windows 的 user32.dll 的方法 MessageBoxA,具体步骤是 Java 中声明一个 native 方法,然后用 javah 命令生成JNI样式的头文件,再自己实现头文件中声明的方法,在实现方法中装载动态库 user32.dll,...

{丸の子} 258

用Python手把手教你实现一个多层感知机(MLP)——从理论到代码实战

本文详细介绍了如何使用Python和Theano库从零开始实现多层感知机(MLP),涵盖从核心原理到代码实战的全过程。通过构建隐藏层、输出层和完整MLP模型,结合权重初始化、激活函数选择和训练技巧,帮助开发者深入理解神经网络工作机制,并应用于实际机器学习任务。

web39explorer的博客 970

uniapp - Invalid value “iife” for option “output.format” - UMD and IIFE output formats are not suppo

Invalid value “iife” for option “output.format” - UMD and IIFE output formats are not supported for code-splitting builds. uniapp 编译报错,vite vue3 Hbuilder 中编译报错,uniapp 打包 App 报错(vue3)hbuilder提示错误,uniapp运行到手机/模拟器 App 报错(vue3)uniapp项目启动报错,如何解决这个问题,安卓app,苹果app

🏆 前端领域优质创作者 3965

如何在Java中调用DLL动态库

调用DLL动态库为Java程序带来了更多可能性。尽管处理本地代码有一定的复杂性,JNI和JNA提供了桥接Java与本地代码的有效方法。通过以上示例,希望你能够对如何在Java中加载和调用DLL库有一个清晰的理解,并能成功集成到你的应用程序中。

恋上、小幸福的博客 6034

第6篇:ESP32连接无源喇叭播放音乐《涛声依旧》

相邻两个音之间的倍数是2^(1/12),约等于1.0594630943592952645618252949463)。这样一来,高八度的do频率是低八度do的两倍。我们把频率440赫兹作为中央C ,C调的歌就是把频率440赫兹当作do,乐谱中写作:1=C。一个八度分成12份,八个八度的十二平均音率对应的频率如下(从33Hz到7902Hz)。相邻的两个音之间的差一个半音,12345671之间的间隔分别是“全全半全全全半”。D调的歌就是把从440后面第二个音494赫兹当作do,乐谱中写作1=D。

Txwtech 1424

Java调用C++的动态库

最近在研究动态库调用的问题,想用Java调用我写好的C++的动态库。经过不断地尝试,终于实现了我想要的功能,网上也看了很多资料,最终整理出来这个文档,希望对有需要的朋友有帮助。 JNI JNI是Java Native Interface的缩写,通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植。 从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。总之就一句话,要用Java调用第三方的动态库,用JNI就对了! Java要调用第三方的动

weixin_43926268的博客 7347

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

JAVA如何调用C/C++动态库

早在JAVA1.1版本就开始支持,它定义了一种公用的语法,当java和c/c++双方都遵循该语法时,可以互相调用。所以使用JNI不能直接调用一般的C/C++库,而必须借助于一个中间动态库,该中间动态库实现了JAVA-JNI语法-C/C++的转换(或者你所调用的动态库原生就封装了JNI)。如果对C++稍微懂一点,其实使用起来也不难。......

YYniannian的博客 8222

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

JNA —— Java调用C/C++动态库

工作所需,要使用Java调用c/c++的动态库,实现Java程序使用动态库中的函数。 搜索了一番,常用的有JNI、JNA方法。 JNI(Java Native Interface) JNA(Java Native Access) JNI需要Java和c/c++

giveaname的专栏 1万+

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Java动态库调用

1. 方法简介       a). JNI调用动态库: JNI是安装JDK的时候自带的内容,适用场景为开发前就知道动态库需要供Java程序调用,且需要Java程序提供动态库开发的头文件内容。使用相对复杂,且如果是对于已经存在的动态库需要开发中间库来适配  b). Jacob 调用动态库:Jacob是SUN提供的一个用于调用动态库的类库,使用相对简单,不需要二次开发,但是需要手动进行一些配置工

爱清清的专栏 3740

java 调用 动态库_java通过JNA调用动态库

前言老规矩,先说下为什么会有这篇文章。近期对接了一个项目,应接口提供方要求,必须通过动态库调用,一个是为了安全可控,调用方不用知道内部实现,加密、解密、具体的逻辑不需要考虑,只需要调用即可;另一个是封装了统一的GUI界面。总之就是非用动态库不可,然后我查了很多资料,请教了几个大佬,最后在运气的加持下,终于调通了,但整个过程特别坎坷,所以我觉有必要记录下。需要说明的是我们这里采用的是JNA的方式什么...

weixin_34638409的博客 1568
上一篇: 利用JNative实现Java调用动态库
下一篇: 写调用动态链接库DLL的应用程序
lele521
博客等级 码龄20年 0粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值