nandi/rustnimpublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/nandi/rustnim.git
git clone ssh://git@rickub.com/nandi/rustnim.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

036-extern-c.rs · 40 lines · 1.4 KBRust Blame HistoryRaw
Lower `extern "C"` blocks to Nim importc; do not transpile libc 7db7991 nandithebull 2h ago1// An `extern "C"` block declares symbols someone else defines. Nim's
2// `importc` is the same statement, and both are bound by the C ABI, so the
3// two declarations describe one symbol rather than one being a translation of
4// the other. This is what a crate that would otherwise reach for `libc` needs.
5//
6// `libc` itself is not transpiled and should not be: it is 129,594 lines of
7// which 54,544 are constants and 7,660 are declarations like these, against
8// 121 actual function bodies in the whole crate. Nim reaches the same symbols
9// natively, so there is nothing to translate.
10//
11// The C types must be declared honestly. Nim emits a real C prototype where
12// Rust does not, so declaring `strlen` as taking `*const u8` is caught by the
13// C compiler rather than silently linking against a different signature.
14
15#[allow(non_camel_case_types)]
16type c_char = i8;
17#[allow(non_camel_case_types)]
18type size_t = usize;
19
20extern "C" {
21 fn abs(x: i32) -> i32;
22 fn strlen(s: *const c_char) -> size_t;
23 fn atoi(s: *const c_char) -> i32;
24 fn labs(x: i64) -> i64;
25}
26
27fn cstr(b: &[u8]) -> *const c_char {
28 b.as_ptr() as *const c_char
29}
30
31fn main() {
32 unsafe {
33 println!("{} {} {}", abs(-5), abs(0), abs(7));
34 println!("{}", labs(-9000000000));
35 println!("{}", strlen(cstr(b"hello\0")));
36 println!("{}", strlen(cstr(b"\0")));
37 println!("{}", atoi(cstr(b"-1234\0")));
38 println!("{}", atoi(cstr(b"42abc\0")));
39 }
40}