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

猜你喜欢

转载自www.cnblogs.com/ZiYangZhou/p/12182097.html