The api function is:
#[no_mangle]
pub extern "C" fn zlgcan_recv(
device: *const c_void,
channel: u8,
timeout: u32,
buffer: &mut *const CanMessage,
mut error: &mut *const c_char
) -> u32 {
match convert(device as *const ZCanDriver, error) {
Some(v) => {
let timeout = match timeout {
0 => None,
v => Some(v),
};
match unify_recv(v, channel, timeout) {
Ok(v) => {
let size = v.len();
v.iter().for_each(|f| println!("{:x} {:?}", f.arbitration_id(), f.data()));
*buffer = v.as_ptr();
std::mem::forget(v);
size as u32
},
Err(e) => {
set_error(e.to_string(), &mut error);
0
}
}
},
None => 0,
}
}
and the python code is:
error = c_char_p()
buffer = POINTER(CanMessage)()
count = _LIB.zlgcan_recv(self.device, channel, timeout, byref(buffer), byref(error))
if count == 0:
if error.value is not None:
LOG.warning(error.value.decode("utf-8"))
for i in range(count):
raw_msg = buffer[i]
length = raw_msg.len;
print(f"{'%02x' % raw_msg.arbitration_id} length of raw message: {length} - {string_at(raw_msg.data, raw_msg.len)}")
print(f"{[raw_msg.data[j] for j in range(length)]}")
msg = can.Message(
timestamp=raw_msg.timestamp / 1000.,
arbitration_id=raw_msg.arbitration_id,
is_extended_id=raw_msg.is_extended_id,
is_remote_frame=raw_msg.is_remote_frame,
is_error_frame=raw_msg.is_error_frame,
channel=raw_msg.channel,
dlc=length,
data=string_at(raw_msg.data, raw_msg.len), #[raw_msg.data[j] for j in range(length)], # string_at(raw_msg.data, raw_msg.len),
is_fd=raw_msg.is_fd,
bitrate_switch=raw_msg.bitrate_switch,
error_state_indicator=raw_msg.error_state_indicator,
)
The question is:
[raw_msg.data[j] for j in range(length)]
cause Index out of range
and
the data from string_at(raw_msg.data, raw_msg.len)
is not correct