Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Case Analysis of Rust closure

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)05/31 Report--

Most people do not understand the knowledge points of this "Rust closure case Analysis" article, so the editor summarizes the following content, detailed content, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "Rust closure case Analysis" article.

Closures We know that Rust's closure is not just a function pointer, which means that it cannot be used as a callback function pointer to pass directly to the C side. We also know that all closures in Rust implement one of the trait Fn, FnMut, or FnOnce provided by the standard library. Closure syntax | | {} is actually the syntax sugar of the Fn series trait. Rust creates a structure for the "environment", impl one of the appropriate trait, and uses it. So, in theory, we should be able to "split" the closure into two parts, instance data of anonymous types and some kind of function similar to the call () method. In this way, we can get the pointer to the function part of it, thus passing the closure to the C-side code. The way to do this is to first create a generic hook function that, like the argument list of the callback function, builds and invokes the closure. Then create a getter function that takes a reference to the closure as an argument and returns a function pointer. We follow the example designed in the previous section with slight modifications: C side, sum_square_cb function, which receives two integer parameters a, b, a function pointer, a void *; Rust side, defines a getter function get_callback; Rust side, defines a closure, updates the data user_data;Rust side when called, and calls the sum_square_cb defined in C OK, the C side of the code remains the same. Let's look at the two functions hook and get_callback on the Rust side. The code is as follows: / / ffi/example_10/src/main.rs

Unsafe extern fn hook (result: c_int, user_data: * mut c_void) where F: FnMut (c_int), {let closure = & mut * (user_data as * mut F); closure (result);}

Pub fn get_callback (_ closure: & F)-> SumSquareCBwhere F: FnMut (c_int), {hook::} because we want the closure to change its environment, when defining the hook function, we limit the closure implementation to FnMut and take c_int as a parameter. In this sentence let closure = & mut * (user_data as * mut F) in the function body, first convert the * mut c_void pointer to the * mut F pointer, then use * to get its data block, and use & mut to get a variable reference, and finally call the closure. At the same time, the only statement in the get_callback function, hook::, we use a syntax called turbofish:: to explicitly specify the hook function that returns type F. Next, the main function on our Rust side is as follows: fn main () {let mut record = SumRecord::default (); unsafe {let mut closure = | result: c_int | {record.total + = result; record.calls + = 1;}; let callback = get_callback (& closure)

Sum_square_cb (1, 2, callback, & mut closure as * mut _ as * mut c_void)

Sum_square_cb (3,4, callback, & mut closure as * mut _ as * mut c_void);}

Println! ("The sum is {:?}", record);} this let mut closure statement means that closure contains the definition of an anonymous function, rather than the return value after the call, which accepts an argument of type c_int. The reason we use closures is that we need to define a piece of code in advance and actually call it at some later time. Here we store the code that we expect to call in closure. Then we call get_callback, which is very important that the function pointer it returns can only be used on the same closure passed in. Because when we define the hook function, we convert the user_data directly to a pointer to the closure type without any type checking. At the same time, when we call the C-side function sum_square_cb, we get its data by getting the variable reference of the closure variable closure and converting it to a void * pointer twice. Where we use the _ placeholder for the Rust compiler to infer the closure type at that location. The above is about the content of this article "Rust closure case Analysis". I believe we all have a certain understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report