91.将指针还原成指定类型
因为指针不知道里面具体有什么,所以一般约定打上unsafe
申明开发者自己对该部分可用性负责,且在调试的时候也能起强调作用
// tests6.rs
//
// In this example we take a shallow dive into the Rust standard library's
// unsafe functions. Fix all the question marks and todos to make the test
// pass.
//
// Execute `rustlings hint tests6` or use the `hint` watch subcommand for a
// hint.// I AM NOT DONEstruct Foo {a: u128,b: Option<String>,
}/// # Safety
///
/// The `ptr` must contain an owned box of `Foo`.
unsafe fn raw_pointer_to_box(ptr: *mut Foo) -> Box<Foo> {// SAFETY: The `ptr` contains an owned box of `Foo` by contract. We// simply reconstruct the box from that pointer.let mut ret: Box<Foo> = unsafe { Box::from_raw(ptr) };// todo!("The rest of the code goes here")ret.b = Some("hello".to_owned());ret
}#[cfg(test)]
mod tests {use super::*;use std::time::Instant;#[test]fn test_success() {let data = Box::new(Foo { a: 1, b: None });let ptr_1 = &data.a as *const u128 as usize;// SAFETY: We pass an owned box of `Foo`.let ret = unsafe { raw_pointer_to_box(Box::into_raw(data)) };let ptr_2 = &ret.a as *const u128 as usize;assert!(ptr_1 == ptr_2);assert!(ret.b == Some("hello".to_owned()));}
}
92.配置本地环境
首先我们得知道配置文件放在build.rs里面!!!
首先参考文档之后写上指令
"rustc-env=TEST_FOO={}",
然后注释掉下面的 your_command变量即可通过test7
93. 函数签名设置编译参数
这个标签指定了编译的配置参数key-value
设置编译的key-value即可,详情参照文档
let your_command = "rustc-cfg=feature = \"pass\"";
94.设置#[link_name = "myName"]和#[no_mangle]获取原汁原味特定的函数名
有时候经过名称修饰或者编译,函数名会发生变化,在同语言下没有影响,但是在不同语言交互的时候可能会找不到指定的函数名,所以将函数名称固定可以避免此种情况发生
// tests9.rs
//
// Rust is highly capable of sharing FFI interfaces with C/C++ and other statically compiled
// languages, and it can even link within the code itself! It makes it through the extern
// block, just like the code below.
//
// The short string after the `extern` keyword indicates which ABI the externally imported
// function would follow. In this exercise, "Rust" is used, while other variants exists like
// "C" for standard C ABI, "stdcall" for the Windows ABI.
//
// The externally imported functions are declared in the extern blocks, with a semicolon to
// mark the end of signature instead of curly braces. Some attributes can be applied to those
// function declarations to modify the linking behavior, such as #[link_name = ".."] to
// modify the actual symbol names.
//
// If you want to export your symbol to the linking environment, the `extern` keyword can
// also be marked before a function definition with the same ABI string note. The default ABI
// for Rust functions is literally "Rust", so if you want to link against pure Rust functions,
// the whole extern term can be omitted.
//
// Rust mangles symbols by default, just like C++ does. To suppress this behavior and make
// those functions addressable by name, the attribute #[no_mangle] can be applied.
//
// In this exercise, your task is to make the testcase able to call the `my_demo_function` in
// module Foo. the `my_demo_function_alias` is an alias for `my_demo_function`, so the two
// line of code in the testcase should call the same function.
//
// You should NOT modify any existing code except for adding two lines of attributes.// I AM NOT DONEextern "Rust" {fn my_demo_function(a: u32) -> u32;#[link_name = "my_demo_function"]fn my_demo_function_alias(a: u32) -> u32;
}mod Foo {#[no_mangle]// No `extern` equals `extern "Rust"`.fn my_demo_function(a: u32) -> u32 {a}
}#[cfg(test)]
mod tests {use super::*;#[test]fn test_success() {// The externally imported functions are UNSAFE by default// because of untrusted source of other languages. You may// wrap them in safe Rust APIs to ease the burden of callers.//// SAFETY: We know those functions are aliases of a safe// Rust function.unsafe {my_demo_function(123);my_demo_function_alias(456);}}
}
ok完结