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
- Pointers — addresses and how a pointer is stored
- Pointer Types —
*var Tand*opaque, which map onto C pointer types - Foreign Function Interface — declaring and calling native functions
Pointer Arithmetic
Adding an integer to a *T advances the address by multiples of the element size, not by raw bytes. base + 1 moves forward by sizeof(T) bytes so that it lands on the next element, whatever T is. This is most useful when walking a buffer, such as a slice's data pointer.
Overview
A type alias introduces an additional name for an existing type using the type keyword: