// An `extern "C"` block declares symbols someone else defines. Nim's // `importc` is the same statement, and both are bound by the C ABI, so the // two declarations describe one symbol rather than one being a translation of // the other. This is what a crate that would otherwise reach for `libc` needs. // // `libc` itself is not transpiled and should not be: it is 129,594 lines of // which 54,544 are constants and 7,660 are declarations like these, against // 121 actual function bodies in the whole crate. Nim reaches the same symbols // natively, so there is nothing to translate. // // The C types must be declared honestly. Nim emits a real C prototype where // Rust does not, so declaring `strlen` as taking `*const u8` is caught by the // C compiler rather than silently linking against a different signature. #[allow(non_camel_case_types)] type c_char = i8; #[allow(non_camel_case_types)] type size_t = usize; extern "C" { fn abs(x: i32) -> i32; fn strlen(s: *const c_char) -> size_t; fn atoi(s: *const c_char) -> i32; fn labs(x: i64) -> i64; } fn cstr(b: &[u8]) -> *const c_char { b.as_ptr() as *const c_char } fn main() { unsafe { println!("{} {} {}", abs(-5), abs(0), abs(7)); println!("{}", labs(-9000000000)); println!("{}", strlen(cstr(b"hello\0"))); println!("{}", strlen(cstr(b"\0"))); println!("{}", atoi(cstr(b"-1234\0"))); println!("{}", atoi(cstr(b"42abc\0"))); } }