📝 简介
接入了海康 SDK 的项目在 Linux 新内核上开发时启动会报错“无法启用共享目标需要的可执行栈: 无效的参数”。
🚫 尝试方案
-
准备修复后的库文件
# 安装工具 paru -S execstack # 进入项目根目录,提取 JNA 的 .so 文件 mkdir -p libs/jna_fixed unzip -j libs/hc/jna.jar com/sun/jna/linux-amd64/libjnidispatch.so -d libs/jna_fixed # 清除“可执行栈”标记 execstack -c libs/jna_fixed/libjnidispatch.so -
添加 VM 启动参数
-Djna.boot.library.path=/项目绝对路径/libs/jna_fixed
正常了一段时间又报错了。
✅ 最终解决方案
先从 Maven 中央库引入或 jar 文件引入,此处项目是 Gradle implementation 的 jar 文件。
Maven Repository: net.java.dev.jna » jna » 5.18.1
implementation(files('../libs/hc/jna-5.18.1.jar'))
修改HCNetSDK.java:
-
新增适配 JNA 5.x 的结构体基类。
import java.util.ArrayList; import java.lang.reflect.Field; import java.lang.reflect.Modifier; public interface HCNetSDK extends Library { // …… public static class SdkStructure extends Structure { @Override protected List<String> getFieldOrder() { List<String> fieldOrderList = new ArrayList<String>(); for (Class<?> clazz = getClass(); !clazz.equals(HCNetSDK.SdkStructure.class); clazz = clazz.getSuperclass()) { Field[] fields = clazz.getDeclaredFields(); int modifiers; for (Field field : fields) { modifiers = field.getModifiers(); if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) { continue; } fieldOrderList.add(field.getName()); } } return fieldOrderList; } @Override public int fieldOffset(String name) { return super.fieldOffset(name); } } } -
所有
extends Structure替换为extends SdkStructure,注意FRAME_INFO需要改成HCNetSDK.SdkStructure。public static class NET_DVR_SCHEDTIME extends SdkStructure { // …… } public class FRAME_INFO extends HCNetSDK.SdkStructure { // …… }
评论区