如何将盒装切片 (`Box<[T]>`) 传递给 C 函数?
Posted
技术标签:
【中文标题】如何将盒装切片 (`Box<[T]>`) 传递给 C 函数?【英文标题】:How to pass a boxed slice (`Box<[T]>`) to a C function? 【发布时间】:2017-01-12 20:50:47 【问题描述】:我想向 C 函数公开一个“动态数组”。 C 函数将拥有数据,稍后将调用我的函数来释放数据。所以它看起来像下面这样:
fn get_something(len: *mut usize) -> *mut u8;
fn dealloc_something(data: *mut u8, len: usize);
在内部我有一个Box<[T]>
(my_vec.to_boxed_slice()
)。我可以很容易地获得大小/长度,但我不知道应该返回哪个指针。如果我将从boxed_slice.as_mut_ptr()
返回的指针传递给Box::from_raw()
,应用程序将崩溃。但是,如果我传递从 Box::into_raw
返回的指针,我无法找到内存布局的保证(指针指向数组的第一个元素,并且将在所有未来的 Rust 版本中继续这样做)。
这里有什么解决办法?
【问题讨论】:
【参考方案1】:Box::into_raw
返回一个指向已分配存储开头的指针。切片是内存中连续的项目序列。因此,指针指向切片中的第一项。如果Box::into_raw
返回任何其他内容,它就不会真正有用。
boxed_slice.as_mut_ptr()
和 Box::into_raw
之间的主要区别在于,Box::into_raw
获得了 box 的所有权但不释放它,而 boxed_slice.as_mut_ptr()
只是返回指针的副本并将 Box
的所有权留给您的函数,因此编译器会在返回之前隐式删除它。这意味着当您使用boxed_slice.as_mut_ptr()
时,您实际上是在返回一个指向已释放内存的指针!
【讨论】:
这意味着当你使用boxed_slice.as_mut_ptr()
时,你实际上是在返回一个指向释放内存的指针...实际上我使用的是mem::forget
,但这不是很重要。
你能把我链接到这种内存布局的参考吗? Box::into_raw
会返回指向第一个元素的指针吗?如果这是真的,我的问题得到了回答,我不需要再问任何其他问题了。
“切片是一个内存块的视图,表示为一个指针和一个长度。” doc。未指定切片数据的内存布局。您需要在切片上调用as_mut_ptr
以获取指向数据的有效指针。
@vinipsmaker:您可能想file an issue(如果还没有的话)要求澄清文档。以上是关于如何将盒装切片 (`Box<[T]>`) 传递给 C 函数?的主要内容,如果未能解决你的问题,请参考以下文章