最近工作上需要用java调用C接口,在这里记录一下。
非专业人员,有不同意见欢迎评论区交流。
java调用c接口一般有两种方案,JNI和JNA,JNI性能更好,使用复杂,JNA性能一般,使用简单,这里是简单用一下,所以用了JNA。
在github上找了个maven的demo,调不通,最后没有用maven。
目录结构
MyProject/
├── libs/
│ ├── jna.jar
│ └── platform.jar
├── CaptureUtil.java
└── libkysdk-screenshot.so
下载JNA
先建一个目录libs,下载jna需要的两个jar包,下载地址
准备so库
在这里我要调用api在libkysdk-screenshot.so,所以把so库放在项目路径下。
(也可以不放,记住位置)
调用代码
import com.sun.jna.Library;
import com.sun.jna.Native;
import java.io.File;
public class CaptureUtil {
public interface Capture extends Library {
// 要调用的api的java定义
int kdk_capture_screen_to_file(String filepath, String filename, String display);
// 加载动态链接库
Capture INSTANCE = (Capture) Native.loadLibrary("kysdk-screenshot", Capture.class);
}
// 静态块用于加载本地库
static {
// 设置JNA查找库的方式,这里可以指定库的位置或者使用默认路径
String libraryPath = "/home/XXX/libkysdk-screenshot.so";
File file = new File(libraryPath);
if (!file.exists()) {
throw new RuntimeException("Library not found: " + libraryPath);
}
System.load(file.getAbsolutePath());
}
public static void main(String[] args) {
// 获取环境变量
String home = System.getenv("HOME");
// 显示器参数应该是字符串而不是字符指针
String display = ":0";
System.out.println("***************************");
// 调用库函数,并且打印返回值
int result = Capture.INSTANCE.kdk_capture_screen_to_file(home, "test.png", display);
System.out.println(result);
System.out.println("***************************");
}
}
编译语句:
javac -cp libs/jna-5.15.0.jar:libs/jna-platform-5.15.0.jar CaptureUtil.java
执行语句:
java -cp .:libs/jna-5.15.0.jar:libs/jna-platform-5.15.0.jar CaptureUtil
这样就完成了调用。