私は要素のペアを構築しようとしています:
array: *mut T
array_len: usize
array
はデータを所有することを目的としています
ただし、 Box::into_raw
は*mut [T]
を返します。生のポインタをスライスに変換するための情報が見つかりません。メモリ内のレイアウトは何ですか? Cからどのように使用しますか? *mut T
に変換する必要がありますか?もしそうなら、どのように?
C関数でVec
を可変的に借用したいだけの場合は、次のように実行できます。
extern "C" {
fn some_c_function(ptr: *mut i32, len: ffi::size_t);
}
fn safe_wrapper(a: &mut [i32]) {
unsafe {
some_c_function(a.as_mut_ptr(), a.len() as ffi::size_t);
}
}
もちろん、エイリアシングの仮定を破る可能性があるため、C関数はこのポインタを別の場所に格納しないでください。
データの「所有権をCコードに渡す」場合は、次のようにします。
use std::mem;
extern "C" {
fn c_sink(ptr: *mut i32, len: ffi::size_t);
}
fn sink_wrapper(mut vec: Vec<i32>) {
vec.shrink_to_fit();
assert!(vec.len() == vec.capacity());
let ptr = vec.as_mut_ptr();
let len = vec.len();
mem::forget(vec); // prevent deallocation in Rust
// The array is still there but no Rust object
// feels responsible. We only have ptr/len now
// to reach it.
unsafe {
c_sink(ptr, len as ffi::size_t);
}
}
ここで、C関数は、たとえばRust関数を呼び出して割り当てを解除することにより、最終的にポインターと長さをRustに返すことを期待するという意味で「所有権を取得」します。
#[no_mangle]
/// This is intended for the C code to call for deallocating the
/// Rust-allocated i32 array.
unsafe extern "C" fn deallocate_Rust_buffer(ptr: *mut i32, len: ffi::size_t) {
let len = len as usize;
drop(Vec::from_raw_parts(ptr, len, len));
}
Vec::from_raw_parts
は、ポインター、サイズ、容量の3つのパラメーターを想定しているため、何らかの方法で容量も追跡するか、ポインターと長さをCに渡す前にVecのshrink_to_fit
を使用する必要があります。関数。ただし、これには再割り当てが含まれる場合があります。
[T]::as_mut_ptr
を使用して、*mut T
、Vec<T>
、またはその他のDerefMut-to-sliceタイプから直接Box<[T]>
ポインタを取得できます。
use std::mem;
let mut boxed_slice: Box<[T]> = vector.into_boxed_slice();
let array: *mut T = boxed_slice.as_mut_ptr();
let array_len: usize = boxed_slice.len();
// Prevent the slice from being destroyed (Leak the memory).
mem::forget(boxed_slice);