3 ms·
Super cool! Is there a reason the Rust-exported functions aren't marked with `extern "C"`?
by dikaiosune 10y ago
Super cool!
Is there a reason the Rust-exported functions aren't marked with `extern "C"`?
- the_mitsuhiko 10y agoI must admit I don't know. It does not appear to be necessary, I assume it's implied in one way or another for `no_mangle` extern functions. However I must also admit that I did not look into the exact mechanics. I do know that if you bind to a function that is linked in that you need it.
- loeg 10y agoIt's for C++ consumers of C libraries. Doesn't matter for Python <-> Rust.
- the_mitsuhiko 10y agoThere is an extern C in Rust as well however which should enforce c calling conventions.
- loeg 10y agoRight, but `extern "C"` is for C++ programs using C library headers directly. Rust doesn't use C headers directly, I think, so it wouldn't need this kludge.
- tomjakubowski 10y agoI think you may be confused. The original commenter wasn't referring to use of 'extern "C"' in the C header file, but to its (lack of) use in the Rust source that defines those functions.
- deleted 10y ago[deleted]
- mbrubeck 10y ago`#[no_mangle]` is currently a bit overloaded; there's discussion of whether this is correct or not: https://internals.rust-lang.org/t/precise-semantics-of-no-mangle/4098 https://internals.rust-lang.org/t/precise-semantics-of-no-ma...
- wyldfire 10y agoAre you referring to the declarations in libsourcemap.h or the definitions in cabi.rs? Regarding the declarations: this would only be necessary if processed in C++ context, to change the name mangling/linkage features of the declarations. For portability sometimes authors hide these behind "ifdef __cplusplus" barriers, but it's not really critical here. Regarding the definitions: "Exposing a C ABI in Rust" from the article describes this in detail. For the most part, "#[no_mangle]" has the same effect that "extern "C"" has on linkage/mangling in C++.
- eridius 10y ago#[no_mangle] turns off the name mangling so it emits a symbol in the style C would. But AFAIK it doesn't force the function to use C calling conventions. As demonstrated in https://doc.rust-lang.org/book/ffi.html#calling-rust-code-from-c https://doc.rust-lang.org/book/ffi.html#calling-rust-code-fr... you probably still need the `extern` keyword on your function definition, e.g. #[no_mangle] pub extern unsafe fn lsm_view_from_json(bytes: *const u8, len: c_uint, err_out: *mut CError) -> *mut View { ... }
- dikaiosune 10y agoI'm referring to the definitions of the Rust functions. As far as I know, `#[no_mangle]` disables name-mangling but doesn't change the ABI of a function. That's what `extern "C"` is for in Rust -- to declare a function with the C ABI. You can have a Rust ABI function with an unmangled name (what it looks is done in the post) and you can have a C ABI function in Rust with a mangled name (by using `extern "C"` but not `#[no_mangle]` -- for example for C callbacks). Based on my limited understanding of C++, `extern "c"` in C++ is equivalent to using both `#[no_mangle]` and `pub extern "C"` in Rust. I would guess that much of the time failing to specify a C ABI would work out fine unless you try to accept or pass non-FFI types (enums, references, etc) but I'm not sure. It's confusing as hell. There was a thread about the mixed up semantics somewhat recently on the internals forum: https://internals.rust-lang.org/t/no-no-mangle/3973 https://internals.rust-lang.org/t/no-no-mangle/3973 (edit: and also https://internals.rust-lang.org/t/precise-semantics-of-no-mangle/4098 https://internals.rust-lang.org/t/precise-semantics-of-no-ma...). If you look at the LLVM IR generated from https://is.gd/Hfup3X https://is.gd/Hfup3X you can see that the extern "C" fn differs in that it's given a `nounwind` attribute, among other things.