JNA调用DLL简单使用
Posted ziyangzhou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JNA调用DLL简单使用相关的知识,希望对你有一定的参考价值。
java系统中调用dll动态链接库需要用到JNA作为桥接工具,特此记录一下JNA的使用方式。
引入JNA的jar包
直接下载或者通过maven导入jar包,maven引入版本为5.5.0的JNA配置如下
<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna-platform -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.5.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.5.0</version>
</dependency>
Hello World
通过JNA调用C标准库的printf()函数。
package test.javatest.jna;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
public class HelloWorld {
public interface CLibrary2 extends Library {
CLibrary2 INSTANCE = (CLibrary2) Native.load((Platform.isWindows() ? "msvcrt" : "c"), CLibrary2.class);
void printf(String format, Object... args);
}
public static void main(String[] args) {
CLibrary2.INSTANCE.printf("Hello, World
");
for (int i = 0; i < args.length; i++) {
CLibrary2.INSTANCE.printf("Argument %d: %s
", i, args[i]);
}
}
}
类型映射
官方文档 Default Type Mappings# Default Type Mappings
Native Type | Size | Java Type | Common Windows Types |
---|---|---|---|
char | 8-bit integer | byte | BYTE, TCHAR |
short | 16-bit integer | short | WORD |
wchar_t | 16/32-bit character | char | TCHAR |
int | 32-bit integer | int | DWORD |
int | boolean value | boolean | BOOL |
long | 32/64-bit integer | NativeLong | LONG |
long long | 64-bit integer | long | __int64 |
float | 32-bit FP | float | - |
double | 64-bit FP | double | - |
char* | C string | String | LPCSTR |
void* | pointer | Pointer | LPVOID, HANDLE, LP_XXX_ |
返回值和参数
获取函数返回值
有加密文件接口int encryptFile(char* filePath,char* key),其中filePath为输入的文件路径,key为输入的秘钥,返回值0或者1标识是否加密成功。
根据类型映射定义接口
int encryptFile(String filepath, String key);
调用接口
@Test
public void testEncryptFile() {
try {
int code = ThirdpartyLib.INSTANCE.encryptFile("D:\test\测试文档.pdf", "123456");
System.out.println("testEncryptFile code = " + code);
} catch (Exception e) {
e.printStackTrace();
}
}
获取函数的参数返回值
有获取秘钥接口void getEncryptKey(char* encryptKey,int* size),其中encryptKey为输出的秘钥,size为输入的秘钥长度。
使用Pointer类型定义接口
void getEncryptKey(Pointer encryptKeyPointer,IntByReference intByReference);
调用接口,指针类型类型输出参数的接口我们需要预先开辟一块指定大小的内存区域用于存放数据,需要提前知道或者预估出数据的大小。对于指针类型的输出参数根据具体情况使用IntByReference
,LongByReference
,PointerByReference
,Pointer
等。
@Test
public void testGetEncryptKey() {
Pointer pointer = new Memory(128);
IntByReference intByReference = new IntByReference();
ThirdpartyLib.INSTANCE.getEncryptKey(pointer,intByReference);
System.out.println("testGetEncryptKey encryptKey = " + pointer.getString(0) + " ,size = " + intByReference.getValue());
pointer.getPointer(0);
}
完整代码
package test.javatest.jna;
import org.junit.Test;
import com.sun.jna.Library;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
public class JNATest {
public interface ThirdpartyLib extends Library {
ThirdpartyLib INSTANCE = Native.load("D:\test\DLL\test\bin\Debug\test.dll", ThirdpartyLib.class);
int encryptFile(String filepath, String key);
void getEncryptKey(Pointer encryptKeyPointer,IntByReference intByReference);
}
@Test
public void testEncryptFile() {
try {
int code = ThirdpartyLib.INSTANCE.encryptFile("D:\test\测试文档.pdf", "123456");
System.out.println("testEncryptFile code = " + code);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testGetEncryptKey() {
Pointer pointer = new Memory(128);
IntByReference intByReference = new IntByReference();
ThirdpartyLib.INSTANCE.getEncryptKey(pointer,intByReference);
System.out.println("testGetEncryptKey encryptKey = " + pointer.getString(0) + " ,size = " + intByReference.getValue());
pointer.getPointer(0);
}
}
参考
https://github.com/java-native-access/jna
https://blog.csdn.net/blog_abel/article/details/32334881
以上是关于JNA调用DLL简单使用的主要内容,如果未能解决你的问题,请参考以下文章