c - C 互操作的原始指针
问题描述
要在 Python 中使用一些 Rust 代码,我认为它需要通过 C 接口传递,为我正在使用的接口(CFFI)执行此操作,我相信我需要返回大量原始指针(它注释The ctype is usually some constant string describing the C type. It must be a pointer or array type.
)。我对此有困难。
简明扼要地解释起来有点困难,所以提前,这是一个问题的游乐场:https ://play.rust-lang.org/?version=nightly&mode=release&edition=2018&gist=d541592aa6011e5d67c279680f855743
我有一个返回复杂类型的函数:
fn test_function() -> CArray<CArray<SymbolPixels>> {
// Just some test data
let temp: Vec<Vec<(Vec<u8>, Bound<usize>)>> = vec![
vec![(vec![1,2,3,4,5,6,7],Bound::new())],
vec![(vec![1,2,3,4,5,6,7],Bound::new()),(vec![1,2,3,4,5,6,7],Bound::new()),(vec![1,2,3,4,5,6,7],Bound::new())]
];
CArray::new(temp.into_iter().map(|sl| {
CArray::new(sl.into_iter().map(|(s, b)| SymbolPixels {
pixels: &CArray::new(s),
bound: &ReturnBound::new(b)
}).collect::<Vec<SymbolPixels>>())
}).collect::<Vec<CArray<SymbolPixels>>>())
}
#[derive(Clone, Debug)]
pub struct Bound<T: Ord + Copy> {
pub min: Point<T>,
pub max: Point<T>,
}
// This impl is just for easy testing here
impl Bound<usize> {
fn new() -> Bound<usize> {
Bound { min: Point { x:1, y:2 }, max: Point { x:5, y:9 } }
}
}
#[repr(C)]
#[derive(Debug)]
pub struct CArray<T> {
pub ptr: *const T,
pub size: usize,
}
impl<T> CArray<T> {
pub fn new(v: Vec<T>) -> Self {
let (ptr,size,_) = v.into_raw_parts();
CArray {
ptr: ptr,
size: size,
}
}
}
#[repr(C)]
#[derive(Debug)]
pub struct SymbolPixels {
pub pixels: *const CArray<u8>,
pub bound: *const ReturnBound
}
#[repr(C)]
#[derive(Debug)]
pub struct ReturnBound {
pub min: *const Point<u32>,
pub max: *const Point<u32>,
}
impl ReturnBound {
pub fn new(b: Bound<usize>) -> Self {
ReturnBound {
min: &Point { x: b.min.x as u32, y: b.min.y as u32 },
max: &Point { x: b.max.x as u32, y: b.max.y as u32 }
}
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct Point<T: Ord> {
pub x: T,
pub y: T,
}
目前正在尝试读取返回结果:
fn main() {
let segment = test_function();
unsafe {
println!("segment: {:.?}",segment);
let lines = std::slice::from_raw_parts(segment.ptr, segment.size);
println!("lines: {:.?}",lines);
for line in lines.iter() {
let symbols = std::slice::from_raw_parts(line.ptr, line.size);
for s in symbols.iter() {
println!("{:.?}",*s.bound);
// THE PROBLEM:
// The below line doesn't work
println!("{:.?}",*(s.bound).min);
// (Rust throws an error and it simply crashes the Python program when access is attempted)
}
}
}
}
我收到错误消息(有时操场会崩溃):
Compiling playground v0.0.1 (/playground)
error[E0615]: attempted to take value of method `min` on type `*const ReturnBound`
--> src/main.rs:16:45
|
16 | println!("{:.?}",*(s.bound).min);
| ^^^ method, not a field
|
help: use parentheses to call the method
|
16 | println!("{:.?}",*(s.bound).min(_));
| ^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0615`.
error: could not compile `playground`
To learn more, run the command again with --verbose.
我相当确定这是我在这里滥用指针的结果,我非常感谢任何帮助。
解决方案
编译器错误消息具有误导性。试试println!("{:.?}",(*s.bound).min);
吧。
推荐阅读
- javascript - 获取数据键值并包含在 .html 之前的 URL 中
- azure - 在 Azure API 管理中检查 traceparent http 标头的正确性
- c++ - CMake将依赖项添加到表亲目录中的内部库
- php - 如何利用数据数组中的存储过程处理函数
- android - Android 10:如何以编程方式删除 MediaStore 项目及其在文件系统上的关联数据?
- angular - 如何使用 ControlValueAccessor 在角度 8 中默认选择垫按钮切换
- c++ - C++ Linux 服务初始化
- apache-spark - 什么是最佳火花:联合然后加入或加入然后联合?
- javascript - 如何测试条件渲染组件的状态转换
- sass - 使用 CSS 模块全局导入外部样式表