If you've followed this entire series, you've seen how Skink handles the modern world. But let's be honest: the modern world is built on a foundation of C code that’s older than most of the people reading this. Eventually, you’ll find a library, a driver, or a piece of legacy magic that you simply have to use.
That’s where C interoperability comes in. It’s the "in case of emergency, break glass" part of the language.
Calling out to the void (extern functions)
If you have a C function you need to call, just tell Skink where it is with extern fn. The compiler will do its best to link it up, provided you don't break the rules of C's memory management.
module main
// Telling the compiler: "Trust me, this exists in C"
extern fn getpid() -> int
fn main() -> int {
pid := getpid()
print("Current process ID: {pid}")
return 0
}
The header shortcut
If you’re lucky enough to have a header file, don't waste your time redeclaring every function. Just import the header.
import "C:mylib.h"
Just remember: you're now responsible for linking the object file or shared library when you compile. If you get a "linker error," don't panic—it's just the machine telling you it can't find the ghost you’re trying to summon.
Don't reinvent the wheel: std/libc
We've already done the heavy lifting for you for the most common stuff. std/libc is your go-to for standard C library functions, wrapped up in a way that won't make you want to scream.
import "std/libc"
fn main() -> int {
text := "hello from the C world"
print("Length: {libc.strlen(text)}")
return 0
}
A word of advice: Wrap it up
Don't go sprinkling raw C calls all over your project. If you find yourself calling getpid() in every file, wrap it in a nice, safe Skink function.
fn getMyPid() -> int {
return getpid()
}
Your future self (and anyone else trying to read your code) will thank you when you decide to migrate that logic later.
Exercises
- The User ID: Call getuid() and print your user ID to the console. It's the Unix way of saying "hello."
- The Buffer Shuffle: Use std/libc to copy a string using strncpy. It's a classic—and a great way to see how manual memory management feels compared to Skink's usual safety.
- The Custom Link: Write a tiny math.c file with a function that adds two integers. Compile it, link it to a Skink program, and call it. It’s a rite of passage.
Congratulations
You've made it. You've walked through the basics, seen the potential traps, and hopefully avoided the worst of the "midnight debugging" sessions. Skink is a powerful tool, and now it's yours to wield.
Go out there and build something resilient.
Happy coding.
For the adventurous, we next look at Async and await.