5.2.2. C Integration: Calling daslang Functions

This tutorial shows how to pass arguments to daslang functions from C and retrieve their return values. It covers all the common scalar types (int, float, string, bool) and introduces the complex result (cmres) calling convention for functions that return structures.

5.2.2.1. Arguments and return values

Every value crossing the C ↔ daslang boundary is carried in a vec4f — a 128-bit SSE register. The API provides symmetric helper pairs:

Packing (C → daslang)

Unpacking (daslang → C)

das_result_int(value)

das_argument_int(vec4f)

das_result_float(value)

das_argument_float(vec4f)

das_result_string(value)

das_argument_string(vec4f)

das_result_bool(value)

das_argument_bool(vec4f)

Despite their names, the das_result_* helpers are also used to pack arguments into a vec4f array before calling a daslang function.

5.2.2.2. Calling a function with arguments

// Find the function (must be [export] in the script).
das_function * fn = das_context_find_function(ctx, "add");

// Pack two int arguments into a vec4f array.
vec4f args[2];
args[0] = das_result_int(17);
args[1] = das_result_int(25);

// Call and unpack the int return value.
vec4f ret = das_context_eval_with_catch(ctx, fn, args);
int result = das_argument_int(ret);    // 42

The corresponding daslang function:

[export]
def add(a : int; b : int) : int {
    return a + b
}

5.2.2.3. String arguments and return values

Strings are passed as plain char * pointers. When daslang returns a string, it lives on the context’s heap and remains valid until the context is released:

vec4f args[1];
args[0] = das_result_string("World");

vec4f ret = das_context_eval_with_catch(ctx, fn_greet, args);
char * greeting = das_argument_string(ret);
printf("%s\n", greeting);   // "Hello, World!"

5.2.2.4. Returning structures (complex results)

When a daslang function returns a struct, use das_context_eval_with_catch_cmres. You allocate the struct on the C side and pass a pointer:

typedef struct { float x; float y; } Vec2;

vec4f args[2];
args[0] = das_result_float(1.5f);
args[1] = das_result_float(2.5f);

Vec2 v;
das_context_eval_with_catch_cmres(ctx, fn_make_vec2, args, &v);
printf("x=%.1f y=%.1f\n", v.x, v.y);   // x=1.5 y=2.5

The C struct layout must match the daslang struct exactly (same field order, same types, same padding).

5.2.2.5. Building and running

cmake --build build --config Release --target integration_c_02
bin\Release\integration_c_02.exe

Expected output:

add(17, 25) = 42
square(3.5) = 12.25
greet("World") = "Hello, World!"
int=42 float=3.14 string=test bool=true
make_vec2(1.5, 2.5) = { x=1.5, y=2.5 }

See also

Full source: 02_calling_functions.c, 02_calling_functions.das

Previous tutorial: tutorial_integration_c_hello_world

Next tutorial: tutorial_integration_c_binding_types

type_mangling — complete type mangling reference