Dealing with out structures
Friday 26 January 2007.
By the same authors
jnative
JNative Howto
Adding a simple function call to User32/Kernel32/Foo java wrapper class
Callbacks are working now !!!!
New features on JNative v1.0
Download/Téléchargement
This is a simple DLL call that puts its output in a structure :
I take the example of Kernel32’s GetSystemTime() for example as asked by Rods
This is the comment of the out structure you can find it on the msdn
/**
* SystemTime
*
* <pre>
* typedef struct _SYSTEMTIME {
* WORD wYear;
* WORD wMonth;
* WORD wDayOfWeek;
* WORD wDay;
* WORD wHour;
* WORD wMinute;
* WORD wSecond;
* WORD wMilliseconds;
* } SYSTEMTIME,
* </pre>
*/
Then we need to translate that in a Java class. It will be based on a help class that was designed for that usage : AbstractBasicData this class is a generic one since its method getValue() will return an object of the parametrized type. So this its declaration :
public static class SystemTime extends AbstractBasicData<SystemTime> {
Note the static keyword since GetSystemTime() will be a static method of Kernel32 and SystemTime an inner class of Kernel32.
The C WORD type is two byte storage area : its counterpart in Java is short type so :
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
Note the public access : this is not very good design since those members may only be read by Java classes. They should be private with only a getter method. This article is not a Java course so we don’t mind.
We need to implement abstract methods of AbstractBasicData :
public int getSizeOf()
This method must return the size[color=red][/color] of the structure. Here is 16 since a WORD is 2 bytes and there is 8 WORDS.
public int getSizeOf() {
return 8*2; //8 WORDS of 2 bytes
}
public Pointer createPointer()
This method creates a new native storage area, it’s generally called once in the constructor.
public Pointer createPointer() throws NativeException {
pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(getSizeOf()));
return pointer;
}
The pointer member is inherited from AbstractBasicData.
public SystemTime getValueFromPointer()
This method copies the native values in the Java variables. Do not misuse this method and getValue() getValue() returns the Java object without coping the native values !!! If you don’t mind loosing some milliseconds, override getValue() and return getValueFromPointer() in it.
public SystemTime getValueFromPointer() throws NativeException {
wYear = getNextShort();
wMonth = getNextShort();
wDayOfWeek = getNextShort();
wDay = getNextShort();
wHour = getNextShort();
wMinute = getNextShort();
wSecond = getNextShort();
wMilliseconds = getNextShort();
return this;
}
The constructor
The AbstractBasicData constructor takes one parameter which is the default value, in this case we only need to create the native memory block.
public SystemTime() throws NativeException {
super(null);
createPointer();
mValue = this;
}
Note the mValue = this; line, so when calling getValue() it will return this.
The function call in the Kernel32 DLL :
public static SystemTime GetSystemTime() throws Exception {
//Create a JNative object called nGetSystemTime : here
JNative nGetSystemTime = new JNative("Kernel32.dll", "GetSystemTime");
//Create a SystemTime object that holds the native out structure
SystemTime systemTime = new SystemTime();
//Pass its pointer address as the first parameter (first is zero !!!)
nGetSystemTime.setParameter(0, systemTime.getPointer());
//Invoke the native GetSystemTime function
nGetSystemTime.invoke();
//Return the populated SystemTime object
return systemTime.getValueFromPointer();
}
And now the complete code :
--------------------------------------------------------------------------------
/**
* SystemTime
*
* <pre>
* typedef struct _SYSTEMTIME {
* WORD wYear;
* WORD wMonth;
* WORD wDayOfWeek;
* WORD wDay;
* WORD wHour;
* WORD wMinute;
* WORD wSecond;
* WORD wMilliseconds;
* } SYSTEMTIME,
* </pre>
*/
public static class SystemTime extends AbstractBasicData<SystemTime> {
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
public Pointer createPointer() throws NativeException {
pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(getSizeOf()));
return pointer;
}
public int getSizeOf() {
return 8*2; //8 WORDS of 2 bytes
}
public SystemTime getValueFromPointer() throws NativeException {
wYear = getNextShort();
wMonth = getNextShort();
wDayOfWeek = getNextShort();
wDay = getNextShort();
wHour = getNextShort();
wMinute = getNextShort();
wSecond = getNextShort();
wMilliseconds = getNextShort();
return this;
}
public SystemTime() throws NativeException {
super(null);
createPointer();
mValue = this;
}
@Override
public String toString() {
return wYear + "/" + wMonth+"/"+wDay+" at + "+wHour+":"+wMinute+":"+wSecond+":"+wMlliseconds;
}
}
public static SystemTime GetSystemTime() throws NativeException, IllegalAccessException {
JNative nGetSystemTime = new JNative(DLL_NAME, "GetSystemTime");
SystemTime systemTime = new SystemTime();
nGetSystemTime.setParameter(0, systemTime.getPointer());
nGetSystemTime.invoke();
return systemTime.getValueFromPointer();
}
public static void main(String[] args) throws NativeException, IllegalAccessException {
System.err.println(GetSystemTime());
}
--------------------------------------------------------------------------------
And the output : 2007/1/26 at 21:45:19:718
I hope this little tutorial can help some of you lazy guys ;)
— Marc
Reply to this article
分享到:
相关推荐
jnative包用于调用dll动态库,目前(2011-12-20)最新版本为1.4RC2,官方正式版本文档为1.3,详见官方地址: http://jnative.free.fr/docs/ 这是最新的帮助文档HTML离线包,希望对大家有帮助 Packages org.xvolks....
《深入解析org.xvolks.jnative源码》 在Java世界中,为了实现与本地代码的交互,开发者经常需要借助JNI(Java Native Interface)技术。然而,JNI的使用门槛相对较高,涉及到C/C++编程,这给许多Java开发者带来了...
《深入理解JNative:Java调用DLL的桥梁》 在Java世界中,由于其平台无关性的特性,直接调用本地动态链接库(DLL)并非易事。然而,JNative库的出现,为Java程序员提供了一个方便的解决方案,使得Java能够无缝地与C/...
JNative是一个Java库,它为Java程序员提供了一种直接调用这些本地代码的能力,无需通过JNI(Java Native Interface)的复杂过程。 JNative的核心思想是将Java方法与本地函数绑定,使得Java代码可以像调用普通Java...
1. **导入JNative.jar**: 将`JNative.jar`添加到项目的类路径中,这样Java虚拟机(JVM)就能找到并加载这个库。 2. **声明本地方法**: 在Java类中使用`native`关键字声明本地方法。例如: ```java public class ...
**JNative API说明文档** **一、JNative简介** JNative是Java平台上的一个库,它允许Java程序直接调用本地(C/C++)代码,实现了Java与原生代码的无缝交互。通过JNative,开发者可以利用Java的跨平台优势,同时...
JNative getstring = new JNative("libmylib.so", "getstring"); getstring.setRetVal(Type.STRING); getstring.invoke(); System.out.println(getstring.getRetVal()); } } 4.输出结果 this is in test_a.....
标题中的"JNative.jar"和"JNativeCpp.dll"是两个关键组件,分别代表Java和C++之间的交互层。在IT行业中,这样的组合通常用于实现Java应用与原生系统资源的紧密集成,例如调用操作系统底层功能或者加速计算密集型任务...
《Jnative资源包源码详解》 Jnative是一款强大的Java本地接口库,它允许Java程序直接调用C和C++的动态链接库(DLL或.so文件),极大地拓展了Java平台的功能。本文将深入探讨Jnative的核心概念、工作原理以及如何在...
这里我们关注的工具是`jnative`,它是一个Java本地接口(Java Native Interface,JNI)的实现,允许Java代码直接调用C++编写的动态链接库(DLL)或共享库(如libJNativeCpp.so在Linux系统中)。这个过程涉及的知识点...
JNative完全自学手册 本手册旨在帮助读者完全深度理解掌握JNative核心技术,通过实例众多的讲解,让读者快速掌握JNative技术。 JNative是Java Native Interface的缩写,允许Java程序调用本地函数库,实现Java程序...
《JNative综合学习指南》 在Java编程世界中,JNative是一个重要的工具,它允许Java程序直接调用本地(C/C++)代码,打破了Java原生的“一次编写,到处运行”的沙箱环境,为开发者提供了更强大的功能扩展能力。...
标题中的“jnative调用动态库”指的是Java中使用JNative库来调用本地(操作系统级别的)动态链接库(DLL或SO文件)的技术。在Java中,为了与操作系统底层功能进行交互,比如调用C/C++编译的库,我们可以使用Java ...
《JNative.jar包详解》 在Java编程领域,我们经常需要与本地代码进行交互,以利用C++或C等语言的高效性能或者调用特定的系统功能。这就是JNI(Java Native Interface)发挥作用的地方。JNative.jar包就是这样一个...
在Java程序中调用DLL(动态链接库)文件通常是通过JNI(Java Native Interface)来实现的,而JNative是JNI的一个封装库,它提供了一种更简洁的方式来调用C/C++编写的本地代码。这篇博客文章可能介绍了如何利用...
在这个场景中,我们关注的是JNative,一个简化Java调用C/C++库的开源库。 JNative 的优点在于它的易用性、数据类型处理的高效以及对回调函数的支持。在使用JNative之前,我们需要了解一些基本概念。例如,`...
**JNative:Java与本地代码交互的桥梁** 在Java编程中,有时我们需要调用本地操作系统提供的功能,或者利用已有的C/C++库,这时就需要用到JNative这样的库。JNative是一个开源的Java本地接口(JNI)工具包,它简化...
JNative库是实现这一目标的一种工具,它允许Java代码通过JNI(Java Native Interface)来调用C/C++编写的本地代码,进而调用Win32 API。JNative-1.3.2版本提供了对这一功能的支持。 首先,我们来理解一下Java ...
《深入解析JNative:连接Java与C++的桥梁》 JNative,作为一款强大的库,为Java程序员提供了与C++代码交互的能力。它允许Java应用程序调用C++编写的动态链接库(DLL或.so),从而扩展了Java的功能,特别是在处理...
《JNative:Java调用C++的桥梁》 在IT领域,跨语言通信是一个常见的需求,比如Java开发者可能需要调用C或C++编写的库来实现特定功能。JNative正是这样一个工具,它允许Java程序无缝地调用本地(Native)代码,尤其...