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,但是下位机收不到数据
我的解答思路和尝试过的方法
我怀疑是结构体有问题,但又不清楚问题在哪,有人帮忙看看不