Building native libraries
Build a library other languages can call.
On this page
Valk can build a shared or static library that C, or any language that calls C, can link against. Mark the functions to expose with export.
Export functions#
Valk
export fn multiply(left: i32, right: i32) i32 {
return left * right
}
struct Vec2 {
x: f32
y: f32
}
export fn vec2_add(a: Vec2, b: Vec2) Vec2 {
return Vec2 { x: a.x + b.x, y: a.y + b.y }
}
Rules for exported functions:
- The signature must be concrete: no generics.
- Arguments and results cannot hold GC-managed data such as
String,Arrayor class objects. Use numbers, structs and raw pointers. - Structs are passed by value with the C layout and calling convention.
- No
fn main()is needed.
Build a shared library#
Terminal
valk build src --lib -o libmath
| OS | Output |
|---|---|
| Linux | libmath.so |
| macOS | libmath.dylib |
| Windows | libmath.dll |
Build a static library#
Terminal
valk build src --lib --static-lib -o libmath # libmath.a or libmath.lib
valk build src --lib --static-lib --static -o libmath # with dependencies inside
Without --static, the program that links the archive also links its dependencies, such as libc. With --static they are put in the archive.
Call it from C#
Declare the functions in a header with matching types:
C
#include <stdio.h>
typedef struct { float x; float y; } Vec2;
int multiply(int left, int right);
Vec2 vec2_add(Vec2 a, Vec2 b);
int main(void) {
printf("%d\n", multiply(6, 7));
Vec2 v = vec2_add((Vec2){1, 2}, (Vec2){3, 4});
printf("%.1f %.1f\n", v.x, v.y);
}
Terminal
cc main.c -L. -lmath -o main
LD_LIBRARY_PATH=. ./main # 42, then 4.0 6.0
Pass data across#
To hand over more than numbers and structs, agree on a pointer protocol: for example, the caller passes a buffer and its length, and Valk writes into it with @ptrv or mem. Memory allocated on one side should be freed by the same side.
