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\n");
        for (int i = 0; i < args.length; i++) {
            CLibrary2.INSTANCE.printf("Argument %d: %s\n", 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

原文地址:https://www.cnblogs.com/ZiYangZhou/p/12182097.html

时间: 2024-10-10 13:16:36

JNA调用DLL简单使用的相关文章

JNA调用DLL报 java.lang.UnsatisfiedLinkError

//最直接的方式是将umsDevTool_sp30.dll放在System32下面,Mapper接口继承Library Mapper instance3 = (Mapper) Native.loadLibrary("umsDevTool_sp30", Mapper.class); 使用JNA时加载动态库,报错如下: Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load li

jna调用c编写的dll

我们团队目前开发的产品是用java语言编写的,大家都知道,java编写的代码随便都可以被反编译,导致别人可能会看到你“裸奔”的样子.所以,为了避免这种安全隐患,团队最终商定,将部分核心代码改用c语言编写,封装为dll,再由java调用. 于是乎,我们就开始jna初探.今天通过各种百度,终于做了个例子出来,在此做个记录,以备后路之需. 1.构造一个dll 由于本机的vs2015没有安装c++模块,所以采用Dev-C++开发,具体步骤如下: 1.1.新建项目,选择DLL,C项目 1.2.删除自动生成

Java-JNA调用DLL(转)

源:JNA调用DLL 介绍 给大家介绍一个最新的访问本机代码的Java框架—JNA. JNA(Java Native Access)框架是一个开源的Java框架,是SUN公司主导开发的,建立在经典的JNI的基础之上的一个框架. JNA项目地址:https://jna.dev.java.net/ 非常强大.易用,功能上类似与.NET的P/Invoke. 不堪回首的JNI 我们知道,使用JNI调用.dll/.so共享类库是非常非常麻烦和痛苦的. 如果有一个现有的.dll/.so文件,如果使用JNI技

Atitit.java&#160;jna&#160;&#160;调用c&#160;&#160;c++&#160;dll的原理与实践&#160;&#160;总结&#160;&#160;v2&#160;&#160;q27

Atitit.java jna  调用c  c++ dll的原理与实践  总结  v2  q27 1. Jna简单介绍1 2. Jna范例halo owrld1 3. Jna概念2 3.1. (1)需要定义一个接口,继承自Library 或StdCallLibrary2 3.2. 2)接口内部定义2 4. 数据类型映射 NA官方给出的默认类型映射表如下:3 5.  JNA能完全替代JNI吗?3 6. 参考4 1. Jna简单介绍 原来使用JNI,你必须手工用C写一个动态链接库,在C语言中映射Ja

Atitit.java&#160;jna&#160;调用c++&#160;dll&#160;的总结

Atitit.java jna 调用c++ dll 的总结 1. JNA技术解密1 1.1. JNA工作原理1 2. JNA技术难点 Java—C和操作系统数据类型的对应表1 2.1. 1 2.2. JNA编程过程3 2.2.1. 跨平台.跨语言调用的第一原则:就是尽量使用基本.简单的数据类型,尽量少跨语言.平台传递数据!4 3. 参考4 1. JNA技术解密 1.1. JNA工作原理 JNA是建立在JNI技术基础之上的一个Java类库,它使您可以方便地使用java直接访问动态链接库中的函数.

JNA调用Delphi7的DLL传递接收中文参数的方法

项目要写个DLL调用硬件,因为人力资源的原因只能用Delphi7开发,结果发现传递中文有点问题,研究了一番后解决,其实很简单,关键是使用system.pas下的编码解码方法.以下在本机测试通过. 环境: Win7 64位旗舰版 JDK1.6 x86 MyEclipse8.6 Delphi7 Delphi代码: library Project2; uses SysUtils, Dialogs; {$R *.res} function testDLL(sInput: PChar):PChar; st

Java框架JNA调用C方法(windows链接库dll文件、linux链接库so文件)

介绍 给大家介绍一个最新的访问本机代码的Java框架-JNA. JNA(Java Native Access)框架是一个开源的Java框架,是SUN公司主导开发的,建立在经典的JNI的基础之上的一个框架. JNA项目地址:https://jna.dev.java.net/ 非常强大.易用,功能上类似与.NET的P/Invoke. 不堪回首的JNI 我们知道,使用JNI调用.dll/.so共享类库是非常非常麻烦和痛苦的. 如果有一个现有的.dll/.so文件,如果使用JNI技术调用,我们首先需要另

Jna调用动态链接库

最近由于工作需要,在和其它系统交互的问题上不仅仅是WebService的交互,还需要利用Java调用其它语言编写的动态链接库,例如编译好的dll文件.好,简单看一下这个问题的来源. 我们的系统和其它系统进行交互的时候,需要网络这个阶段,这段期间数据很容易被截获,这就需要对一些敏感的数据进行加密.通常单个系统我们会用MD5进行加密,无法逆向破解,相对来说还是比较安全的,已经足够使用了.但是为了网络中传输的数据也是密文,这就需要再次进行加密了,所谓的私钥,公钥.经典的例如:DES,加强版3DES等.

java中调用dll文件的两种方法

一中是用JNA方法,另外是用JNative方法,两种都是转载来的, JNA地址:http://blog.csdn.net/shendl/article/details/3589676   JNative地址:http://www.jb51.net/article/35232.htm JNA方法: 介绍 给大家介绍一个最新的访问本机代码的Java框架—JNA. JNA(Java Native Access)框架是一个开源的Java框架,是SUN公司主导开发的,建立在经典的JNI的基础之上的一个框架