xlCanTransmit()函数无法正常工作

时间:2019-09-18 14:36:39

标签: c++ jna

我正在尝试使用xlCanTransmit方法发送CAN帧。问题在于它返回0(XL_SUCCESS),但是该框架为空。框架中只有零。


IVxlApi.s_xl_event eventMsg = new IVxlApi.s_xl_event();

...
...

xlStatus = dll.xlCanTransmit(GlobalConfig.g_xlPortHandle, GlobalConfig.g_xlChannelMask[channelIndex],
                pEventCount, eventMsg.getPointer());

在调用函数xlCanTransmit()之后,将发送该帧,但是其中没有数据。该函数是从dll文件中调用的,您无法对其进行调试。

我的映射结构

 public static class s_xl_event extends Structure {

        public byte tag;
        public byte chanIndex;
        public byte[] transId = new byte[SHORT];
        public byte[] portHandle = new byte[SHORT];
        public byte flags;
        public byte reserved;
        public byte[] timeStamp = new byte[LONG];
        public s_xl_tag_data tagData;

        @Override
        public void read() {
            // read from native memory, populate tag
            super.read();
            // set union type based on tag
            switch (tag) {
                case XL_RECEIVE_MSG:
                case XL_TRANSMIT_MSG:
                    tagData.setType(s_xl_can_msg.class);
                    break;
                case XL_CHIP_STATE:
                    tagData.setType(s_xl_chip_state.class);
                    break;
                case XL_LIN_MSG:
                    tagData.setType(s_xl_lin_msg_api.class);
                    break;
                case XL_SYNC_PULSE:
                    tagData.setType(s_xl_sync_pulse.class);
                    break;
                case XL_RECEIVE_DAIO_DATA:
                    tagData.setType(s_xl_daio_data.class);
                    break;
                case XL_TRANSCEIVER:
                    tagData.setType(s_xl_transceiver.class);
                    break;
                case XL_RECEIVE_DAIO_PIGGY:
                    tagData.setType(s_xl_daio_piggy_data.class);
                    break;
                case XL_KLINE_MSG:
                    tagData.setType(s_xl_kline_data.class);
                    break;
                default:
                    // add default type or throw exception etc. 
                    tagData.setType(s_xl_can_msg.class);
                    break;
            }
            // now read tagData from native memory
            tagData.read();
        }

        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("tag", "chanIndex", "transId", "portHandle", "flags", "reserved", "timeStamp", "tagData");
        }
    }

CANoe Trace中的CAN框架

enter image description here

本机端的函数如下所示

DECL_STDXL_FUNC(xlCanTransmit, XLCANTRANSMIT, (
        XLportHandle  portHandle,
        XLaccess      accessMask,
        unsigned int* pEventCount,
        void* pEvents)
    );

我在Java中的映射


short xlCanTransmit(long portHandle, long accessMask, IntByReference pEventCount, Pointer pEvents);

我手动编写了一些随机数据,并调用了xlCanTransmit()函数。

但是在CANoe跟踪中,我只能看到没有数据和ID的空框架。

我的Java发送函数


 public short send(String txID, String dlc, String[] data, int channelIndex) {
        short xlStatus = IVxlApi.XL_ERROR;

        IntByReference pEventCount = new IntByReference(1);
        IVxlApi.s_xl_event eventMsg = new IVxlApi.s_xl_event();

        eventMsg.tag = IVxlApi.XL_TRANSMIT_MSG;

        eventMsg.tagData.msg.id[0] = 2;// = Long.parseLong(txID);

        eventMsg.tagData.msg.dlc[0] = 8;// = Short.parseShort(dlc);
        eventMsg.tagData.msg.flags[0] = 0;

        eventMsg.tagData.msg.data[0] = Byte.parseByte(data[0]);
        eventMsg.tagData.msg.data[1] = Byte.parseByte(data[1]);
        eventMsg.tagData.msg.data[2] = Byte.parseByte(data[2]);
        eventMsg.tagData.msg.data[3] = Byte.parseByte(data[3]);
        eventMsg.tagData.msg.data[4] = Byte.parseByte(data[4]);
        eventMsg.tagData.msg.data[5] = Byte.parseByte(data[5]);
        eventMsg.tagData.msg.data[6] = Byte.parseByte(data[6]);
        eventMsg.tagData.msg.data[7] = Byte.parseByte(data[7]);

        /*if(true){
            eventMsg.tagData.msg.id  |= IVxlApi.XL_CAN_EXT_MSG_ID;
        }*/
        eventMsg.write();
        xlStatus = dll.xlCanTransmit(GlobalConfig.g_xlPortHandle, GlobalConfig.g_xlChannelMask[channelIndex],
                pEventCount, eventMsg.getPointer());

         eventMsg.read();


        return xlStatus;
    }


CANoe Trace中的CAN框架

enter image description here

在调用tagData.read()(第475行)之后,数据初始化为零 enter image description here

1 个答案:

答案 0 :(得分:0)

返回值0表示在本机端正确执行了该功能,但您尚未将本机内存复制回Java。

通常在您在函数中传递Structure时自动完成此操作,但是您已经将Pointer传递给了结构。您的最后一个参数是eventMsg.getPointer()。直到您告知Pointer到您的结构,JNA才会知道它如何映射,并且按照当前的调用方式,它需要使用read()将值复制回JNA。 / p>

调用该函数后,只需执行eventMsg.read()即可获得所需的结果,但更好的解决方法是首先将Structure传递给该函数,然后让JNA进行转换指向指针并自动为您read()。更改函数调用以将eventMsg作为参数传递。