Hi guys! I am translating a C program into rust. I have a C struct
struct _sapi_module_struct {
char *name;
char *pretty_name;
int(*startup)(struct _sapi_module_struct *sapi_module);
int(*shutdown)(struct _sapi_module_struct *sapi_module);
...
}
And Bindgen translated it into:
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _sapi_module_struct {
pub name: *mut ::std::os::raw::c_char,
pub pretty_name: *mut ::std::os::raw::c_char,
pub startup: ::std::option::Option<
unsafe extern "C" fn(sapi_module: *mut _sapi_module_struct) -> ::std::os::raw::c_int,
,
pub shutdown: ::std::option::Option<
unsafe extern "C" fn(sapi_module: *mut _sapi_module_struct) -> ::std::os::raw::c_int,
,
......
}
You see, the startup and shutdown members of the struct are function pointers. But in rust they are wrapped by Option. I want to call startup. But I have a failed try. See my following figure.
Can someone help me? Thank you!
Hi! It's easier for us to read your code if you follow the formatting guidelines:
To format code in this forum you need to surround the code with three backticks (```). For example, typing this...
```
fn main() {
println!()
}
```
...will be rendered as highlighted Rust code, like so:
fn main() {
println!()
}
You can also tell the forum software which language you're using by adding the language after the opening backticks.
```cpp
#include <iostream>
int main() {
std::cout << "Hello World!";
}
```
Will appear with highlighting as:
#include <iostream>
int main(…
I may have thought of the solution myself: just use a simple match statement.
2 Likes
Your application looks very similar to the solution I proposed for another question:
What about adding another wrapper which implements Drop?
#[repr(C)]
struct Schema {
destroy: Option<unsafe extern "C" fn(*mut Schema)>,
...
}
extern "C" { fn some_external_function() -> *mut Schema; }
/// A Rust wrapper which manages a [`Schema`]'s lifetime and gives it
/// convenient methods or trait implementations.
struct SchemaHandle(*mut Schema);
impl Drop for SchemaHandle {
fn drop(&mut self) {
if let Some(destroy) = (*self.0).destroy {
unsafe { destroy(self.0); }
…
#[repr(C)]
struct Foo {
destroy: Option<unsafe extern "C" fn(*mut Foo)>,
}
impl Drop for Foo {
fn drop(&mut self) {
if let Some(destructor) = self.destroy {
unsafe { destructor(self); }
}
}
}
The idea is you can use an if-let statement to execute a block of code if the expression matches a single variant.
system
Closed
August 2, 2021, 4:40am
5
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.