Skip to content

Instantly share code, notes, and snippets.

@EarlGray
Created June 9, 2025 18:04
Show Gist options
  • Save EarlGray/2ccdaa1e48a0d99b162ae52a7752460c to your computer and use it in GitHub Desktop.
Save EarlGray/2ccdaa1e48a0d99b162ae52a7752460c to your computer and use it in GitHub Desktop.
"works on my machine" Rust -> C -> Rust `Box<dyn Any>` ffi
void free_box_any(void *dat, void *tbl);
void take_boxptr(void *boxptr, void *tblptr) {
free_box_any(boxptr, tblptr);
}
extern crate cc;
fn main() {
cc::Build::new().file("boxany.c").compile("boxany");
println!("cargo::rustc-link-lib=boxany");
}
[package]
name = "boxany"
version = "0.1.0"
edition = "2024"
[dependencies]
[build-dependencies]
cc = "1.0"
use std::any::Any;
unsafe extern "C" {
fn take_boxptr(boxptr: *mut (), tblptr: *mut ());
}
#[unsafe(no_mangle)]
pub extern "C" fn free_box_any(datptr: *mut (), tblptr: *mut ()) {
let boxany: Box<dyn Any> = unsafe {
std::mem::transmute((datptr, tblptr))
};
std::mem::drop(boxany);
}
pub unsafe fn send_box(boxany: Box<dyn Any>) {
unsafe {
let (boxptr, tblptr): (*mut (), *mut ()) =
std::mem::transmute(boxany);
take_boxptr(boxptr, tblptr);
}
}
struct Foo(String);
impl Drop for Foo {
fn drop(&mut self) {
println!("Foo::drop()");
}
}
fn main() {
let boxany: Box<dyn Any> = Box::new(Foo(String::from("test string")));
unsafe { send_box(boxany) }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment