Skip to content

Instantly share code, notes, and snippets.

@dacci
Last active March 16, 2023 22:33
Show Gist options
  • Save dacci/ee8b8ead08369c2f9c186aa142084e2d to your computer and use it in GitHub Desktop.
Save dacci/ee8b8ead08369c2f9c186aa142084e2d to your computer and use it in GitHub Desktop.
How to call blocks written in C from Rust
Rust: key = 0x10299ff88, block = 0x16d462c20
C: answer = 42
C: len = 18
Rust: key = 0x0, block = 0x0
C: len = 0
use std::ffi::{c_char, c_int, c_void};
#[repr(C)]
struct Block {
isa: *const c_void,
flags: c_int,
reserved: c_int,
invoke: unsafe extern "C" fn(*const Self, *const c_char) -> c_int,
}
#[no_mangle]
extern "C" fn interop_invoke(key: *const c_char, block: *const Block) -> c_int {
println!("Rust: key = {key:?}, block = {block:?}");
if block.is_null() {
0
} else {
unsafe { ((*block).invoke)(block, key) }
}
}
#include <stdio.h>
extern int interop_invoke(const char*, int (^)(const char*));
int main() {
int answer = 42;
int len = interop_invoke("answer", ^(const char* key) {
return printf(" C: %s = %d\n", key, answer);
});
printf(" C: len = %d\n", len);
len = interop_invoke(NULL, NULL);
printf(" C: len = %d\n", len);
return 0;
}
.PHONY: all clean
all: main
main: main.c libblock.dylib
libblock.dylib: lib.rs
rustc --crate-type cdylib $^ -o $@
clean:
rm -f main libblock.dylib
@dacci
Copy link
Author

dacci commented Nov 8, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment