听雨烹茶 2024-08-26 10:06 采纳率: 33.3%
浏览 13
已结题

(SADPSDK-Java|SadpDataCallBack-Java实现)

海康SADPJava实现中发现SadpDataCallBack多次调用。
局域网中只有两个设备,1是测试文本。SADP通过jna实现了C动态链接库
应该是线程问题,但我的代码中未涉及相关代码。
发生问题:

img

相关代码如下

package com.cmct.webcam.service.impl;

import com.cmct.webcam.api.SADP;
import com.cmct.webcam.model.Device;
import com.cmct.webcam.service.DeviceService;
import com.sun.jna.Pointer;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import lombok.SneakyThrows;

import static com.cmct.webcam.util.utils.byteArrayToString;

public class DeviceServiceImpl implements DeviceService {

    @SneakyThrows
    public void init(){
        sadp.SADP_SetLogToFile(3,"./SadpLog",3);
        boolean iRet = sadp.SADP_Start_V40(DeviceServiceImpl::SadpDataCallBack,0, Pointer.NULL);
        if (!iRet) {
            int iError = sadp.SADP_GetLastError();
            System.out.println("SADP_Start_V40 failed: " + iError);
        }
        sadp.SADP_SetAutoRequestInterval(10);
        Thread.sleep(1000);
    }
    // 设备信息回调,添加设备信息
    private static void SadpDataCallBack(SADP.SADP_DEVICE_INFO_V40 lpDeviceInfoV40, Pointer pUserDate) {
        System.out.println("1");
        //list.add(toDevice(lpDeviceInfoV40.struSadpDeviceInfo));
    }
    // 类型转换
    static Device toDevice(SADP.SADP_DEVICE_INFO sadpDeviceInfo) {
        Device device = new Device();
        device.setSzIPv4Address(new SimpleStringProperty(byteArrayToString(sadpDeviceInfo.szIPv4Address)));
        device.setSzDevDesc(new SimpleStringProperty(byteArrayToString(sadpDeviceInfo.szDevDesc)));
        device.setBActivated(new SimpleStringProperty(String.valueOf(sadpDeviceInfo.bActivated).equals("0") ?"激活":"未激活"));
        return device;
    }

    @Override
    public ObservableList<Device> fetchDeviceData() {
        return FXCollections.observableArrayList(list);
    }

}

dll实现的相关代码,SADP

// 回调函数
    // 获取在线设备信息的回调函数
    interface PDEVICE_FIND_CALLBACK_V40 extends Callback {
        void invoke(SADP_DEVICE_INFO_V40 lpDeviceInfo,Pointer pUserDate);
    }
// 3.3 SADP_Start_V40 启动 SADP 服务
    boolean SADP_Start_V40(PDEVICE_FIND_CALLBACK_V40 pDeviceFindCallBack,int bInstallNPF, Pointer pUserData);

我的调用方式

new DeviceServiceImpl().init();
  • 写回答

1条回答 默认 最新

  • 吃不了席 2024-08-26 17:36
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    从你的描述和代码来看,SadpDataCallBack 被多次调用的问题可能是由于 SADP 服务在局域网中检测到多个设备时触发了多次回调。为了解决这个问题,你可以在 SadpDataCallBack 方法中添加一些逻辑来确保每个设备只被处理一次。例如,你可以使用一个 HashSet 来存储已经处理过的设备信息,然后在回调方法中检查设备是否已经被处理过。

    首先,在你的 DeviceServiceImpl 类中添加一个 HashSet 来存储已处理的设备信息:

    private Set<String> processedDevices = new HashSet<>();
    

    然后,修改 SadpDataCallBack 方法,以便在处理设备信息之前检查设备是否已经被处理过:

    private static void SadpDataCallBack(SADP.SADP_DEVICE_INFO_V40 lpDeviceInfoV40, Pointer pUserDate) {
        String deviceId = byteArrayToString(lpDeviceInfoV40.szIPv4Address);
        if (!processedDevices.contains(deviceId)) {
            System.out.println("1");
            //list.add(toDevice(lpDeviceInfoV40.struSadpDeviceInfo));
            processedDevices.add(deviceId);
        }
    }
    

    这样,即使 SADP 服务多次触发回调,每个设备也只会被处理一次。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 9月6日
  • 已采纳回答 8月29日
  • 创建了问题 8月26日

悬赏问题

  • ¥15 微信小程序 用oss下载 aliyun-oss-sdk-6.18.0.min client报错
  • ¥15 ArcGIS批量裁剪
  • ¥15 labview程序设计
  • ¥15 为什么在配置Linux系统的时候执行脚本总是出现E: Failed to fetch http:L/cn.archive.ubuntu.com
  • ¥15 Cloudreve保存用户组存储空间大小时报错
  • ¥15 伪标签为什么不能作为弱监督语义分割的结果?
  • ¥15 编一个判断一个区间范围内的数字的个位数的立方和是否等于其本身的程序在输入第1组数据后卡住了(语言-c语言)
  • ¥15 Mac版Fiddler Everywhere4.0.1提示强制更新
  • ¥15 android 集成sentry上报时报错。
  • ¥15 抖音看过的视频,缓存在哪个文件