1.海康的sdk中,java版的demo——clientdemo中,先完成配置,运行起来,添加设备,完成预览。(如下图所示)

java对接海康硬盘录像机 java调用海康sdk开发实例_数据

2.点击“配置”;选择“串口参数”;弹出串口参数配置窗口,如下图:

java对接海康硬盘录像机 java调用海康sdk开发实例_java_02

3.建立透明通道:(此处不配485透传参数,默认相机485配置),选择“数据透传”,串口类型改为“485”;点击“建立透传”按钮,弹出消息提示成功或者失败。

 

java对接海康硬盘录像机 java调用海康sdk开发实例_java_03

5.到了这里似乎透传成功了,但是一点用的没有!!!!

因为clientdemo中透传功能的代码中,建立透明通道的功能没实现。

先要完成代码:

最快的方法,先到clientdemo工程中HCNetSDk类中找到 NET_DVR_SerialStart()接口,查看一下NET_DVR_SerialStart()在什么地方被使用,找到建立透明通道那部分代码:

/*************************************************
    函数:      数据透传  "建立通道" 按钮单击响应函数
    函数描述:	建立透明通道
     *************************************************/
    private void jButtonCreateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCreateActionPerformed
        int iSerialType = jComboBoxSerialType.getSelectedIndex() + 1;//串口类型

        m_lSerialHandle = hCNetSDK.NET_DVR_SerialStart(m_lUserID, new NativeLong(iSerialType), fSerialDataCallBack, 0);


        if (m_lSerialHandle.intValue() == -1)
        {
            JOptionPane.showMessageDialog(this, "建立透明通道失败!");
            System.out.println(hCNetSDK.NET_DVR_GetLastError());
            return;
        } else
        {
            JOptionPane.showMessageDialog(this, "建立透明通道成功建立!");
            jButtonCreate.setEnabled(false);
            jButtonDistruct.setEnabled(true);
        }
    }//GEN-LAST:event_jButtonCreateActionPerformed

首先,上面代码中检测hCNetSDk是否为null,如果为null,则实例化;其次NET_DVR_SerialStart()接口中的回调函数fSerialDataCallBack是否为null,如果为null,则实例化;(代码运行半天,才发现这两变量为null)

当完成这些,还是不行,在回调函数的重载函数FSerialDataCallBack,如下图所示:

/******************************************************************************
     *内部类:   FSerialDataCallBack
     *串口信息回调函数
     ******************************************************************************/
    class FSerialDataCallBack implements HCNetSDK.FSerialDataCallBack
    {

        public void invoke(NativeLong lSerialHandle, String pRecvDataBuffer, int dwBufSize, int dwUser)
        {
            //获取时间,格式化输出
            Date today = new Date();
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        
            //打印时间到jTextAreaMessage
            jTextAreaMessage.append(dateFormat.format(today) + ":\n");
            //打印回调的信息到jTextAreaMessage
            jTextAreaMessage.append(pRecvDataBuffer + "\n");

        }
    }

又到坑人的地方,你可能要从回调函数的pRecvDataBuffer解析出byte[], 但是pRecvDataBuffer.getBytes()转成byte[]并不是你要的透传数据。比如透传数据是10字节,但这样得到的只有8个字节,而且当打印pRecvDataBuffer.toString的值时,乱码;

怎么办?

所以说这是坑人的地方。联系海康客服,客服让你去看sdk中MFC关于透传的代码。然而对Java中对应的代码没有什么借鉴性,别灰心!有解决办法。

在clientdemo工程中HCNetSDk类将FSerialDataCallBack接口做简单的修改。

其中pRecvDataBuffer被定义为String类型,此时需要修改为Pointer类型。如下图所示:

public static interface FSerialDataCallBack extends StdCallCallback {
        public void invoke(NativeLong lSerialHandle,Pointer pRecvDataBuffer,int dwBufSize,int dwUser);
      
}

 当改完HCNetSDk类FSerialDataCallBack接口,在实现透传功能的代码的加载的透传回调函数一定要修改,和HCNetSDk类FSerialDataCallBack接口参数保持一直,(不然你重载的FSerialDataCallBack会报错)。修改后的透传回调函数如下所示:

/******************************************************************************
     *内部类:   FSerialDataCallBack
     *串口信息回调函数
     ******************************************************************************/
    class FSerialDataCallBack implements HCNetSDK.FSerialDataCallBack
    {

        public void invoke(NativeLong lSerialHandle, Pointer pRecvDataBuffer, int dwBufSize, int dwUser)
        {
           
            //获取时间,格式化输出
            Date today = new Date();
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");

            //透传数据转换为byte[], dwBufSize是透传数据的字节数
            //byte[] bytes = pRecvDataBuffer.getByteArray(0, dwBufSize);

            //打印时间到jTextAreaMessage
            jTextAreaMessage.append(dateFormat.format(today) + ":\n");
            //打印回调的信息到jTextAreaMessage, pRecvDataBuffer.getByteArray(0,dwBufSize).toString()将透传数据转换为字符串打印在表格
            jTextAreaMessage.append(pRecvDataBuffer.getByteArray(0,dwBufSize).toString()+ "\n");


        }
    }