diff options
Diffstat (limited to 'vendor/cxx/book/src/binding/rawptr.md')
-rw-r--r-- | vendor/cxx/book/src/binding/rawptr.md | 100 |
1 files changed, 0 insertions, 100 deletions
diff --git a/vendor/cxx/book/src/binding/rawptr.md b/vendor/cxx/book/src/binding/rawptr.md deleted file mode 100644 index 179421127..000000000 --- a/vendor/cxx/book/src/binding/rawptr.md +++ /dev/null @@ -1,100 +0,0 @@ -{{#title *mut T, *const T — Rust ♡ C++}} -# *mut T, *const T - -Generally you should use references (`&mut T`, `&T`) or [std::unique_ptr\<T\>] -where possible over raw pointers, but raw pointers are available too as an -unsafe fallback option. - -[std::unique_ptr\<T\>]: uniqueptr.md - -### Restrictions: - -Extern functions and function pointers taking a raw pointer as an argument must -be declared `unsafe fn` i.e. unsafe to call. The same does not apply to -functions which only *return* a raw pointer, though presumably doing anything -useful with the returned pointer is going to involve unsafe code elsewhere -anyway. - -## Example - -This example illustrates making a Rust call to a canonical C-style `main` -signature involving `char *argv[]`. - -```cpp -// include/args.h - -#pragma once - -void parseArgs(int argc, char *argv[]); -``` - -```cpp -// src/args.cc - -#include "example/include/args.h" -#include <iostream> - -void parseArgs(int argc, char *argv[]) { - std::cout << argc << std::endl; - for (int i = 0; i < argc; i++) { - std::cout << '"' << argv[i] << '"' << std::endl; - } -} -``` - -```rust,noplayground -// src/main.rs - -use std::env; -use std::ffi::CString; -use std::os::raw::c_char; -use std::os::unix::ffi::OsStrExt; -use std::ptr; - -#[cxx::bridge] -mod ffi { - extern "C++" { - include!("example/include/args.h"); - - unsafe fn parseArgs(argc: i32, argv: *mut *mut c_char); - } -} - -fn main() { - // Convert from OsString to nul-terminated CString, truncating each argument - // at the first inner nul byte if present. - let args: Vec<CString> = env::args_os() - .map(|os_str| { - let bytes = os_str.as_bytes(); - CString::new(bytes).unwrap_or_else(|nul_error| { - let nul_position = nul_error.nul_position(); - let mut bytes = nul_error.into_vec(); - bytes.truncate(nul_position); - CString::new(bytes).unwrap() - }) - }) - .collect(); - - // Convert from Vec<CString> of owned strings to Vec<*mut c_char> of - // borrowed string pointers. - // - // Once extern type stabilizes (https://github.com/rust-lang/rust/issues/43467) - // and https://internals.rust-lang.org/t/pre-rfc-make-cstr-a-thin-pointer/6258 - // is implemented, and CStr pointers become thin, we can sidestep this step - // by accumulating the args as Vec<Box<CStr>> up front, then simply casting - // from *mut [Box<CStr>] to *mut [*mut CStr] to *mut *mut c_char. - let argc = args.len(); - let mut argv: Vec<*mut c_char> = Vec::with_capacity(argc + 1); - for arg in &args { - argv.push(arg.as_ptr() as *mut c_char); - } - argv.push(ptr::null_mut()); // Nul terminator. - - unsafe { - ffi::parseArgs(argc as i32, argv.as_mut_ptr()); - } - - // The CStrings go out of scope here. C function must not have held on to - // the pointers beyond this point. -} -``` |