小编ran*_*son的帖子

通过原始指针克隆类型擦除的 Arc 是否安全?

我在我与包裹在一个数据工作的情况Arc,我有时最终使用into_raw,以获得原始指针的基础数据。我的用例还需要类型擦除,因此原始指针通常被强制转换为 a *const c_void,然后在重新构造Arc.

我遇到过这样一种情况,即能够在Arc不需要知道底层数据的具体类型的情况下克隆它会很有用。据我了解,只要我从未真正取消引用数据,Arc仅出于调用目的而使用虚拟类型重建 应该是安全clone的。因此,例如,这应该是安全的:

pub unsafe fn clone_raw(handle: *const c_void) -> *const c_void {
    let original = Arc::from_raw(handle);
    let copy = original.clone();
    mem::forget(original);
    Arc::into_raw(copy)
}
Run Code Online (Sandbox Code Playgroud)

有什么我遗漏的东西会使这实际上不安全吗?另外,我认为答案也适用于Rc,但如果有任何差异,请告诉我!

unsafe type-erasure rust raw-pointer

5
推荐指数
1
解决办法
345
查看次数

在 FFI 中使用 ()(和其他零大小类型)

在 Rust 中执行 FFI 时()(或任何其他零大小类型)的等价物是什么?具体来说,我很好奇()在编写extern "C"函数时作为函数参数最合理的等价物是什么。

我的理解是零大小类型在 C 中无效,但 Rust 似乎允许在extern "C"函数中使用它们,例如:

#[no_mangle]
pub extern "C" fn test_ffi(input: ()) -> () {
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,返回()void在 C# 中声明函数相同。但是,我不清楚input在从 C 生成绑定时如何声明参数。我的印象是 ZST 不能在 C 中表示,因此不应该是 FFI 安全的。似乎nomicon 证实了这一点,说:

为了避免()在 FFI 中使用时出现警告,我们改为使用空数组 ( [u8; 0]),它与空类型一样有效,但与 FFI 兼容。

这似乎暗示这()不是 FFI 兼容的,但那[u8; 0]是(即使我希望它也是零尺寸)?

ffi rust

3
推荐指数
1
解决办法
298
查看次数

标签 统计

rust ×2

ffi ×1

raw-pointer ×1

type-erasure ×1

unsafe ×1