Skip to content

Commit cc2fc48

Browse files
committed
expand nullable pointer example
1 parent 48ce206 commit cc2fc48

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

src/doc/book/ffi.md

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -590,22 +590,42 @@ where `None` corresponds to `null`. So `Option<extern "C" fn(c_int) -> c_int>` i
590590
to represent a nullable function pointer using the C ABI (corresponding to the C type
591591
`int (*)(int)`).
592592

593-
Here is an example:
593+
Here is a contrived example. Let's say some C library has a facility for registering a
594+
callback, which gets called in certain situations. The callback is passed a function pointer
595+
and an integer and it is supposed to run the function with the integer as a parameter. So
596+
we have function pointers flying across the FFI interface in both directions.
594597

595598
```rust
596599
use std::os::raw::c_int;
597600

601+
extern "C" {
602+
/// Register the callback.
603+
fn register(Option<extern "C" fn(Option<extern "C" fn(c_int) -> c_int>, c_int) -> c_int>);
604+
}
605+
598606
/// This fairly useless function receives a function pointer and an integer
599607
/// from C, and returns the result of calling the function with the integer.
600608
/// In case no function is provided, it squares the integer by default.
601-
#[no_mangle]
602-
pub extern fn apply(process: Option<extern "C" fn(c_int) -> c_int>, int: c_int) -> c_int {
609+
extern "C" fn apply(process: Option<extern "C" fn(c_int) -> c_int>, int: c_int) -> c_int {
603610
match process {
604611
Some(f) => unsafe { f(int) },
605612
None => int * int
606613
}
607614
}
608-
# fn main() {}
615+
616+
fn main() {
617+
unsafe {
618+
register(Some(apply));
619+
}
620+
}
621+
```
622+
623+
And the code on the C side looks like this:
624+
625+
```c
626+
void register(void (*f)(void (*)(int), int)) {
627+
...
628+
}
609629
```
610630
611631
No `tranmsute` required!

0 commit comments

Comments
 (0)