8.3.3. C Integration: Binding C Types
This tutorial shows how to create a custom module in C and expose C types (enumerations, structures, aliases) to daslang so that scripts can use them as native types.
8.3.3.1. Creating a module
A module is a named container for types and functions. The script refers to
it with require:
das_module * mod = das_module_create("tutorial_c_03");
The module must be registered before compiling any script that
requires it. After das_initialize(), call your registration
function before das_program_compile.
8.3.3.2. Binding an enumeration
// C enum
typedef enum { Color_red = 0, Color_green = 1, Color_blue = 2 } Color;
// Bind to daslang
das_enumeration * en = das_enumeration_make("Color", "Color", 1);
das_enumeration_add_value(en, "red", "Color_red", Color_red);
das_enumeration_add_value(en, "green", "Color_green", Color_green);
das_enumeration_add_value(en, "blue", "Color_blue", Color_blue);
das_module_bind_enumeration(mod, en);
The third argument to das_enumeration_make is ext (boolean):
non-zero means the enum’s underlying storage is int64; zero (the
common case) means int. The example above passes 1, so Color
is int64-backed — pass 0 for the usual int storage.
In daslang:
let color = Color.green
print("color = {color}\n")
8.3.3.3. Binding a structure
C structures are exposed as handled types. You specify size, alignment, and each field’s offset and mangled type:
typedef struct { float x; float y; } Point2D;
das_structure * st = das_structure_make(lib, "Point2D", "Point2D",
sizeof(Point2D), _Alignof(Point2D));
das_structure_add_field(st, mod, lib, "x", "x", offsetof(Point2D, x), "f");
das_structure_add_field(st, mod, lib, "y", "y", offsetof(Point2D, y), "f");
das_module_bind_structure(mod, st);
In daslang:
var p : Point2D
p.x = 3.0
p.y = 4.0
8.3.3.4. Type mangling reference
Every type in the C API is described by a compact string:
Mangled string |
Type |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handled struct |
See Type Mangling for the complete specification.
8.3.3.5. Binding a type alias
das_module_bind_alias(mod, lib, "IntArray", "1<i>A");
In daslang, IntArray is now a synonym for array<int>.
8.3.3.6. Binding interop functions
Functions that operate on custom types use the standard interop pattern, but their mangled signatures reference the handled type by name:
// def point_distance(p : Point2D) : float
// Mangled: "f H<Point2D>"
vec4f c_point_distance(das_context * ctx, das_node * node, vec4f * args) {
Point2D * p = (Point2D *)das_argument_ptr(args[0]);
float dist = sqrtf(p->x * p->x + p->y * p->y);
return das_result_float(dist);
}
das_module_bind_interop_function(mod, lib, &c_point_distance,
"point_distance", "c_point_distance",
SIDEEFFECTS_none, "f H<Point2D>");
Note the use of das_argument_ptr — structures are passed as pointers.
8.3.3.7. Building and running
cmake --build build --config Release --target integration_c_03
bin\Release\integration_c_03.exe
Expected output:
color = green
numbers = [ 10, 20, 30]
point = (3, 4)
distance from origin = 5
as string: (3.00, 4.00)
See also
Full source:
03_binding_types.c,
03_binding_types.das
Previous tutorial: C Integration: Calling daslang Functions
Next tutorial: C Integration: Callbacks and Closures
Type Mangling — complete type mangling reference