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 DONE
-
- struct 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
{ - // SAFETY: The `ptr` contains an owned box of `Foo` by contract. We
- // simply reconstruct the box from that pointer.
- let mut ret: Box
= 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 DONE
-
- extern "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完结