c - 使用类型 `[my_struct]` 是否是将 C 结构数组传递给 Rust 函数的正确方法?
问题描述
C 文件:
typedef struct point {
int x;
int y;
} point;
typedef struct points {
int count;
point *array_of_points;
} points;
锈文件:
#[derive(Debug)]
#[repr(C)]
pub struct point {
x: c_int,
y: c_int,
}
#[derive(Debug)]
#[repr(C)]
pub struct points {
count: c_int,
array_of_points: [point],
}
#[no_mangle]
pub fn do_something(all_points: &points) {
for i in 0..all_points.count {
let crr_point = &all_points.array_of_points[i as usize];
println!("{:?}", crr_point);
}
}
在我的 C 文件中,我分配了很多 struct point 并将它们添加到array_of_points
,然后我调用该do_something
函数。
我如何array_of_points
在 Rust 中获得每个单点?
我array_of_points
在 Rust 中定义数组的方式是否正确?
当我运行它时,出现了这个奇怪的结果:
point { x: 0, y: -952095696 }
point { x: 32674, y: 101 }
等等。
解决方案
那是未定义的行为。在该类型的 Rust 版本中, type 的成员array_of_points
被point*
转换为 Rust 未调整大小的 slice [point]
,这既不等价也不兼容。通过添加类型的成员[point]
,您建议在其第一个成员之后直接point
具有可变数量的尾随point
对象count
。这也产生points
了一个未调整大小的类型(或动态调整大小的类型)。
C中的内存布局points
应该如下:
[ int, point* ]
|
-->[ point, point, ...] // dynamically allocated
但是那个 Rust 定义是这样的:
[ int, point, point, ... ] // unknown compile time size
points
需要使用原始指针定义成员:
#[derive(Debug)]
#[repr(C)]
pub struct points {
count: c_int,
array_of_points: *mut point,
}
然后do_something
应该通过偏移量取消引用指针以检索每个点:
#[no_mangle]
pub fn do_something(all_points: &points) {
for i in 0..all_points.count {
unsafe {
let crr_point = &*all_points.array_of_points.offset(i as isize);
println!("{:?}", crr_point);
}
}
}
或者从给定的部分构造一个适当的 Rust 切片points
:
#[no_mangle]
pub fn do_something(all_points: &points) {
let point_array = unsafe {
std::slice::from_raw_parts(all_points.array_of_points, all_points.count as usize)
};
for crr_point in point_array {
println!("{:?}", crr_point);
}
}
请注意在任何这些情况下您如何需要代码。 unsafe
也可以看看:
推荐阅读
- asp.net-mvc - Bootstrap 4 从右到左自定义文件输入
- php - 多个父类怎么可能?
- python - 无法在带有 PyCharm 的 Anaconda 环境中使用 windpowerlib?
- c# - 我做了一个滑块,可以在主菜单中调整游戏音量,但是当场景更改为实际游戏时音乐恢复正常?
- scala - 为什么除了错误之外我看不到我的演员级别的日志消息
- android - 我的应用未显示清单文件中的名称
- html - 如何从 p 或 div 中抓取文本,输出给出一个空列表或无
- angular - Angular 应用程序中页脚后的额外空白
- amazon-web-services - 如何连接 AWS 账户
- native-base - 本机基础标签 - 知道如何删除标签周围的边框吗?