Pointers and extern

Pointers are the primary way Rux exchanges memory with C and other native libraries. Typed pointers, *opaque for handles, and the write-through qualifier *var T all map directly onto C pointer types.

extern func memcpy(dst: *opaque, src: *opaque, n: uint) -> *opaque;

let src = [1, 2, 3, 4];
var dst: int32[4];
memcpy(dst.data, src.data, sizeof(int32) * src.length);

Pass a buffer by handing the callee its data pointer and length; the address identifies the first byte and the length bounds the access. Because C strings are null-terminated and Rux slices are not, account for the terminator explicitly when crossing the boundary.

A slice or array exposes its buffer through .data, which is always a read-only *T — so buffers handed to C are declared *T or *opaque even when the native code writes through the underlying memory. Reserve a writable *var T parameter for a scalar out-value you pass with @ on a local var, such as an API that reports how many bytes it wrote.

See the Foreign Function Interface chapter for more on calling native code.

See Also