在64位的树莓派直接使用pi4j会出现java.lang.UnsatisfiedLinkError
主要是pi4j自带的.so动态库是32位的。
因此要解决这个问题就需要编译一个64位的动态库。
为了方便起见,直接在树莓派4b上编译。
-
获取源码
git clone https://github.com/Pi4J/pi4j.git
查找其jni的地方在哪里。
发现是在pi4j-native
文件夹
一直进入到pi4j-native/src/main/native
文件夹
-
编译动态库
可以查看一些build.sh内容发现是一个一键编译的脚本。
包含和各种类型的板子,但是我们不需要,只编译树莓派的就行了
因此执行脚本./build-raspberrypi.sh
其中可能会遇到,tree命令找不到,这个命令就是查看目录结构的,执行到这一步其实已经编译完成了。
进入lib/raspberrypi/dynamic
目录里面有libpi4j.so
- 替换pi4j里的
libpi4j.so
从报错的地方可以看到,加载库的地方是com.pi4j.util.NativeLibraryLoader
类
NativeLibraryLoader
主要是一些兼容和调试的类。
可以看到它其实是把.so动态库,解压到临时文件夹,然后再加载的。
最核心也就是调用系统自带的库加载方法System.load(target.toAbsolutePath().toString());
。
把libpi4j.so放在程序目录。
System.load(new File("libpi4j.so").getAbsolutePath());//加载
虽然能使用了,但是它报错仍然在,只能catch忽略掉了。
或者直接替换pi4j-core-1.2.jar包里面的libpi4j.so。
- 测试
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import static com.pi4j.io.gpio.RaspiPin.GPIO_25;
/**
* @author: luo
* @create: 2020-06-01 14:27
**/
public class Main {
public static void singlePinTest() throws Exception {
GpioController gpio = GpioFactory.getInstance();
GpioPinDigitalOutput pin = gpio.provisionDigitalOutputPin(GPIO_25);
for (int i = 0; i < 10; i++) {
System.out.println("current:" + pin.getState());
pin.toggle();
Thread.sleep(2500);
}
gpio.shutdown();
}
public static void main(String[] args) throws Exception {
singlePinTest();
System.exit(0);
}
}
运行时使用gpio readall
命令查看pin25的状态是变化的