Where PtrAllocator, et al, are traits for allocating a *mut T, cloning a *mut T, and freeing a *mut T respectively. There are reasonable “default” implementations of these traits.
Ptr<T> behaves a lot like a NonNull<T> (actually it uses NonNull internally).
What do you need from such a crate? Do you want reference counted containers? Atomic send/sync compatible containers? Something else?
Fundamental types and methods are there (Box::into_raw(), CStr/CString), but they require boilerplate in each function on the C<=>Rust border.
So I’d love some proc macro that automagically wraps Rust functions like fn foo(x: &str, y: &[i32]) to be exposed as foo(char *, int *, size_t len) to C, and adds a prelude to the function that checks that args are non-NULL, strings are UTF-8, makes slices from pointer + length, etc.
Exposing Rust functions to C can be like magic because you get to work with Rust function signature with Rust types, and you can dictate how C will see them.
Exposing C functions to Rust as some safer, higher-level interface is a messy problem, because C function signatures are ambiguous. There’s no ownership information. It’s not even clear whether a pointer is for 1 thing or an array, so for every char * the user would have to manually specify whether it means CStr, CString, &[u8], CVec<u8>, etc. Not as auto-magic like interfacing the other way.
I'm not sure that those actually solve kornel's expressed need. What they talked about was not the C/C++ header needed for manually written extern "C" functions and constants, but:
So I’d love some proc macro that automagically wraps Rust functions like fn foo(x: &str, y: &[i32]) to be exposed as foo(char *, int *, size_t len) to C, and adds a prelude to the function that checks that args are non-NULL, strings are UTF-8, makes slices from pointer + length, etc.
They were referring to Rust-native functions, with safe, validated inputs, that has no idea if its being called across an FFI boundary, and "magic" taken to basically write an extern unsafe function that safely validates inputs from the FFI boundary, and then calls the native function with correctly validated data and types.