蓝轻尘 2022-09-14 17:09
浏览 13
已结题

JAVA使用JNative二次开发CAN,调用dll中的发送函数,下位机无数据接收

JAVA使用JNative二次开发CAN,调用dll中的发送函数,下位机无数据接收

结构体

typedef struct _VCI_CAN_OBJ {
 UINT ID;
 UINT TimeStamp;
 BYTE TimeFlag;
 BYTE SendType;
 BYTE RemoteFlag;
 BYTE ExternFlag;
 BYTE DataLen;
 BYTE Data[8];
 BYTE Reserved[3];
} VCI_CAN_OBJ, *PVCI_CAN_OBJ;

对应结构体类

package xxx.xxx.xxx;

import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.misc.basicStructures.AbstractBasicData;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;

public class CanObj extends AbstractBasicData<CanObj>{
   public int ID;//帧 ID。32 位变量,数据格式为靠右对齐。
   public long TimeStamp;//设备接收到某一帧的时间标识。只有智能卡才有时间标示,如 USBCAN 系列与PCI-5010/20。时间标示从 CAN 卡上电开始计时,计时单位为 0.1ms。
   public byte TimeFlag;//是否使用时间标识。为 1 时 TimeStamp 有效,TimeFlag 和 TimeStamp 只在此帧为接收帧时有意义。
    /*
   * 发送帧类型。
   * =0 时为正常发送(发送失败会自动重发,重发最长时间为 1.5-3 秒);
   * =1 时为单次发送(只发送一次,不自动重发);
   * =2 时为自发自收(自测试模式,用于测试 CAN 卡是否损坏);
   * =3 时为单次自发自收(单次自测试模式,只发送一次)。
   * 只在此帧为发送帧时有意义。
   * */
   public byte SendType;
   public byte RemoteFlag;//是否是远程帧。=0 时为为数据帧,=1 时为远程帧(数据段空)。
   public byte ExternFlag;//是否是扩展帧。=0 时为标准帧(11 位 ID),=1 时为扩展帧(29 位 ID)。
   public byte DataLen;//数据长度 DLC (<=8),即 CAN 帧 Data 有几个字节。约束了后面 Data[8]中的有效字节。
   public byte[] Data;//CAN 帧的数据。由于 CAN 规定了最大是 8 个字节,所以这里预留了 8 个字节的空间,受 DataLen 约束。如 DataLen 定义为 3,即 Data[0]、Data[1]、Data[2]是有效的。
   public byte Reserved;//系统保留。

    public CanObj() throws NativeException {
        super(null);
        createPointer();
        mValue=this;
    }


    @Override
    public CanObj getValueFromPointer() throws NativeException {
        ID=getNextInt();
        TimeStamp =getNextLong();
        TimeFlag=getNextByte();
        SendType=getNextByte();
        RemoteFlag=getNextByte();
        ExternFlag=getNextByte();
        DataLen=getNextByte();
        Data=new byte[8];
        for (byte datum : Data) {
            datum=getNextByte();

        }
        Reserved=getNextByte();
        return this;
    }

    @Override
    public int getSizeOf() {
        return 8+4+6+8;
    }

    @Override
    public Pointer createPointer() throws NativeException {
        pointer=new Pointer(MemoryBlockFactory.createMemoryBlock(getSizeOf()));
        return pointer;
    }

    public void setID(int ID) throws NativeException {
        this.ID = ID;
        pointer.setIntAt(0,ID);
    }

    public void setTimeStamp(long timeStamp) throws NativeException {
        TimeStamp = timeStamp;
        pointer.setLongAt(4,TimeStamp);
    }

    public void setTimeFlag(byte timeFlag) throws NativeException {
        TimeFlag = timeFlag;
        pointer.setByteAt(11,TimeFlag);
    }

    public void setSendType(byte sendType) throws NativeException {
        SendType = sendType;
        pointer.setByteAt(12,SendType);
    }

    public void setRemoteFlag(byte remoteFlag) throws NativeException {
        RemoteFlag = remoteFlag;
        pointer.setByteAt(13,RemoteFlag);
    }

    public void setExternFlag(byte externFlag) throws NativeException {
        ExternFlag = externFlag;
        pointer.setByteAt(14,ExternFlag);
    }

    public void setDataLen(byte dataLen) throws NativeException {
        DataLen = dataLen;
        pointer.setByteAt(15,DataLen);
    }

    public void setData(byte[] data) throws NativeException {
        Data = data;
        for (byte datum : data) {
            int i=16;
            pointer.setByteAt(i,datum);
            i++;
        }
    }

    public void setReserved(byte reserved) throws NativeException {
        Reserved = reserved;
        pointer.setByteAt(24,Reserved);
    }
}


对应结构体初始化数据

  public static CanObj[] transmitYT(){
        CanObj[] canObjs=new CanObj[1];
        try {
            canObjs[0]=new CanObj();
            canObjs[0].setID(0x0001);
            canObjs[0].setSendType((byte) 0);
            canObjs[0].setRemoteFlag((byte) 0);
            canObjs[0].setExternFlag((byte) 0);
            canObjs[0].setDataLen((byte) 8);
            byte[] bytes=new byte[]{0x64,0x32,0x64,0x32,0x00,0x00,0x32,0x00};
            canObjs[0].setData(bytes);
            canObjs[0].setReserved((byte) 0);
        } catch (NativeException e) {
            throw new RuntimeException(e);
        }

dll中的函数

ULONG __stdcall VCI_Transmit(DWORD DevType, DWORD DevIndex, DWORD CANIndex, 
PVCI_CAN_OBJ pSend, ULONG Len);

java调用函数


```java
 public static int transmit(int devType,int devIndex,int canIndex,CanObj[] canObj,int len){
        JNative jnt=getJnt("Transmit");
        if(jnt==null)
            return -1;
        try {
            for (CanObj obj : canObj) {
                jnt.setRetVal(Type.INT);
                jnt.setParameter(0, devType);
                jnt.setParameter(1, devIndex);
                jnt.setParameter(2, canIndex);
                jnt.setParameter(3, obj.getPointer());
                jnt.setParameter(4, len);
                jnt.invoke();
            }

            System.out.println("transmit:"+jnt.getRetVal());

            return Integer.parseInt(jnt.getRetVal());
        }catch (Exception e){
            e.printStackTrace();
            logger.error("调用transmit方法失败!"+e.getMessage());
            return 0;
        }finally {
            try {
                jnt.dispose();
            } catch (Exception e) {
                logger.error("调用transmit方法中JNT关闭失败!"+e.getMessage());
            }
        }
    }

运行结果及报错内容

目前调用transmit函数,返回1,但是下位机收不到数据

我的解答思路和尝试过的方法

我怀疑是结构体有问题,但又不清楚问题在哪,有人帮忙看看不

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 9月22日
    • 创建了问题 9月14日

    悬赏问题

    • ¥15 更换了一个新的win10系统,再下载VS时碰到的问题,是C++组件的?
    • ¥15 关于罗技鼠标宏lua文件的问题
    • ¥15 halcon ocr mlp 识别问题
    • ¥15 已知曲线满足正余弦函数,根据其峰值,还原出整条曲线
    • ¥20 无法创建新的堆栈防护界面
    • ¥15 sessionStorage在vue中的用法
    • ¥15 wordpress更换域名后用户图片头像不显示
    • ¥15 如何在ubunto上安装CEF (Chromium Embedded Framework),并且基于qt实现打开一个web
    • ¥30 AD9854 为什么输出波形幅度受限,AI机器人勿扰
    • ¥15 如何在ubunto上安装CEF (Chromium Embedded Framework