背景:由于业务需要获取打印机相关信息,对接了打印机厂家,提供了相关的sdk需要二次封装,(windows下是.dll文件,linux下是.so文件)
步骤概述:
1. 定义Java接口:首先,在Java中定义一个接口,声明你想要调用的原生方法。
2. 使用javah生成C头文件:虽然现代JDK版本已不再需要这一步,但理解这个过程有助于明白JNI的工作原理。现在可以直接编写JNI/JNA代码而不需要javah。
3. 编写C/C++代码:根据接口定义,编写包含实现这些原生方法的C/C++代码,并确保遵循Windows下的调用约定(如__stdcall),这通常通过在函数声明中使用__declspec(dllexport)和指定正确的调用约定来完成。
4. 编译C/C++代码为DLL:使用相应的编译器(如Visual Studio或MinGW)编译上述C/C++代码生成动态链接库。
5. 加载和调用DLL中的函数:在Java程序中使用System.loadLibrary加载你的DLL,并通过之前定义的Java接口调用函数。
直接上代码:
引入jna依赖
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.7.0</version>
</dependency>
java编写本地方法:
package org.example;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
public class PrinterClient {
static {
System.loadLibrary("device_pantum_CP1100DN_64");
System.out.println("sdk加载成功!");
}
/**
* 获取设备句柄
* @param printerName
* @param printerHandleRef
* @param nNeededRef
* @return
*/
public native int openPrinter(String printerName, Pointer printerHandleRef, IntByReference nNeededRef);
/**
* 关闭设备句柄
* @param printerHandle
*/
public native void closePrinter(Object printerHandle);
/**
* 获取设备已打印页数
* @param printerHandle
* @param pageNum
* @return
*/
public native int getPrinterPageNum(Object printerHandle, IntByReference pageNum);
}
调用本地方法:
package org.example;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
public class Main {
public static void main(String[] args) {
System.out.print("Hello world!");
PrinterClient printerClient = new PrinterClient();
String property = System.getProperty("java.library.path");
System.out.println(property);
System.out.println("库扫描路径:");
String[] split = property.split(";");
for (String s : split) {
System.out.println(s);
}
System.out.println("获取设备句柄接口:");
IntByReference nNeeded = new IntByReference();
int result = printerClient.openPrinter("Pantum CP1100DN Series PCL6", null, nNeeded);
System.out.println("第一次调用返回: "+result);
System.out.println("nNeeded: "+nNeeded.getValue());
Pointer printer_handle = new Pointer(0);
result = printerClient.openPrinter("Pantum CP1100DN Series PCL6", printer_handle, nNeeded);
System.out.println("第二次调用返回: "+result);
System.out.println("printer_handle: "+printer_handle);
System.out.println("===========================================================================");
System.out.println("关闭设备句柄:");
printerClient.closePrinter(printer_handle);
}
}
结束。
相关参考:
java中调用dll文件的两种方法_java如何调用dll文件-CSDN博客
java函数调用约定_2020-09-04:函数调用约定了解么?-CSDN博客
如何处理Java中的java.lang.UnsatisfiedLinkError错误?-java教程-PHP中文网
Java JNA (四)—— void**、void*、char**、char*、int*等类型映射关系及简单示例_pointerbyreference-CSDN博客