【发布时间】:2019-09-01 21:15:14
【问题描述】:
我正在用 rust 编写一个驱动程序,我有以下 C 结构,我需要将其转换为 Rust 中的等价结构:
struct vfio_irq_set {
__u32 argsz;
__u32 flags;
__u32 index;
__u32 start;
__u32 count;
__u8 data[];
};
给我带来一些问题的唯一变量是数据数组。到目前为止,我有以下锈蚀结构:
#[allow(non_camel_case_types)]
#[repr(C)]
struct vfio_irq_set {
argsz: u32,
flags: u32,
index: u32,
start: u32,
count: u32,
data: *const u8,
}
用于初始化结构并进行ioctl 调用的 rust 代码如下所示:
let irq_set: vfio_irq_set = vfio_irq_set {
argsz: (mem::size_of::<vfio_irq_set>() + mem::size_of::<RawFd>() * (MAX_INTERRUPT_VECTORS + 1) as usize) as u32,
count: interrupt_vector,
flags: VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER,
index: VFIO_PCI_MSIX_IRQ_INDEX as u32,
start: 0,
data: &[event_fd as u8] as *const u8,
};
if unsafe { libc::ioctl(device_fd, VFIO_DEVICE_SET_IRQS, &irq_set) } == -1 {
return Err(format!(
"failed to VFIO_DEVICE_SET_IRQS. Errno: {}",
unsafe { *libc::__errno_location() }
).into());
}
但我总是回复"failed to VFIO_DEVICE_SET_IRQS. Errno: 22"。
有人知道我做错了什么吗?
【问题讨论】:
-
他们不会有相同的布局。灵活的数据成员应该与结构的其余部分在连续的内存中,并且应该只占用存储数据所需的空间。你的例子没有这样做。指针总是占用空间,占用固定数量的空间,指向它的任何数据都不与结构的其余部分连续。
-
另外,
&[event_fd as u8] as *const u8可能不安全:该数组是临时的,寿命不够长。 -
您还将丢失大小信息,因此即使数据不是临时的,也无法安全地读取该数据。
-
是的,你说得对,这只是解决这个问题的绝望方法。我对 rust 很陌生,这是我以前从未见过的 :)