C Interoperability
26.1 Calling C Functions
C declarations use the C. prefix. #include, #flag (compiler/linker flags), and #pkgconfig integrate the build.
#include <stdio.h>
#include <math.h>
#flag -lm
fn C.printf(fmt &char, ...) int
fn C.sqrt(x f64) f64
fn C.strlen(s &char) usize
fn main() {
C.printf(c'Hello from C: %d\n', 42)
println(C.sqrt(16.0))
s := 'hello'
println(C.strlen(&char(s.str)))
}26.2 Flags and Platform-Specific Linking
#flag -I @VMODROOT/c/include
#flag -L @VMODROOT/c/lib
#flag linux -lsqlite3
#flag windows -luser32
#flag darwin -framework Cocoa
#pkgconfig gtk+-3.0
#flag @VMODROOT/c/helper.o
#include "@VMODROOT/c/helper.h"26.3 C Structs, Enums, and Types
#include <time.h>
@[typedef]
struct C.tm {
tm_year int
tm_mon int
tm_mday int
}
fn C.time(t &i64) i64
fn C.localtime(t &i64) &C.tm
fn main() {
mut t := i64(0)
C.time(&t)
tm := C.localtime(&t)
println('${tm.tm_year + 1900}-${tm.tm_mon + 1}-${tm.tm_mday}')
}26.4 Strings and Memory Across the Boundary
v_str := 'hello'
c_ptr := &char(v_str.str) // V string → C string (null-terminated)
back := unsafe { cstring_to_vstring(c_ptr) } // C → V (copies)
back2 := unsafe { tos_clone(&u8(c_ptr)) }
// C callbacks
fn my_cb(x int) int { return x * 2 }
fn C.register_callback(cb fn (int) int)
C.register_callback(my_cb)26.5 Compiling C Sources and Exporting V to C
#flag @VMODROOT/c/fast.c // compile a C source file along with the program
@[export: 'v_add']
pub fn add(a int, b int) int { return a + b }v -shared -o libmylib.so mylib.v # build a shared library
v -o mylib.c mylib.v # emit C source only26.6 Wrapping C Libraries
Write a thin module with C. declarations plus an idiomatic V API (results, structs, free() methods).
Examples in vlib: db.sqlite, db.pg, db.mysql, sokol, stbi, net.openssl, clipboard.
c2v (Module 44) can generate bindings automatically: v translate wrapper header.h.