4.3. C API Reference
The C API (daScriptC.h) provides a pure-C interface for embedding
daslang in applications that cannot use C++. It covers the full
lifecycle: initialization, compilation, simulation, function calls,
type binding, serialization, and sandboxing.
For step-by-step tutorials with compilable examples, see the C integration tutorials.
4.3.1. When to use the C API
The C API is appropriate when:
The host application is written in C (not C++).
You need a stable ABI boundary (e.g. loading daslang as a shared library from another language).
You want to avoid C++ name mangling in your interop layer.
The C++ API (daScript.h) is more ergonomic and exposes more
functionality. The C API covers the most common embedding scenarios
but does not expose every C++ feature (e.g. class adapters, custom
annotations).
4.3.2. Initialization and shutdown
#include "daScript/daScriptC.h"
int main() {
das_initialize();
// ... use daslang ...
das_shutdown();
return 0;
}
das_initialize()Must be called once before any other C API call. Registers all built-in modules.
das_shutdown()Frees all internal structures. Call once when done.
4.3.3. Text output
das_text_writer * tout = das_text_make_printer(); // stdout
das_text_writer * buf = das_text_make_writer(); // string buffer
das_text_output(tout, "hello\n");
das_text_release(tout);
das_text_release(buf);
das_text_make_printer()Creates a writer that prints to stdout.
das_text_make_writer()Creates a writer that accumulates output in an internal buffer.
das_text_release(writer)Frees a text writer.
4.3.4. File access
das_file_access * fAccess = das_fileaccess_make_default();
// ... compile scripts ...
das_fileaccess_release(fAccess);
das_fileaccess_make_default()Creates a filesystem-backed file access.
das_fileaccess_make_project(project_file)Creates a file access backed by a
.das_projectfile for sandboxing. See tutorial_integration_c_sandbox.das_fileaccess_introduce_file(access, name, content, owns)Registers a virtual file from a C string. If
ownsis non-zero, the content is copied; otherwise the caller must keep it alive.das_fileaccess_introduce_file_from_disk(access, name, disk_path)Reads a file from disk and caches it under a virtual path.
das_fileaccess_introduce_daslib(access)Pre-loads all standard library modules into the cache.
das_fileaccess_introduce_native_modules(access)Pre-loads all native plugin modules listed in
external_resolve.inc.das_fileaccess_lock(access)/das_fileaccess_unlock(access)While locked, only pre-introduced files can be accessed — filesystem reads are blocked. Essential for sandboxing.
das_get_root(buf, maxbuf)Copies the daslang root path into
buf.
4.3.5. Compilation
das_module_group * lib = das_modulegroup_make();
das_program * program = das_program_compile(
"script.das", fAccess, tout, lib);
if (das_program_err_count(program) > 0) {
for (int i = 0; i < das_program_err_count(program); i++) {
das_error * err = das_program_get_error(program, i);
das_error_output(err, tout);
}
}
das_program_compile(file, access, tout, libgroup)Compiles a
.dasfile. Always returns non-NULL; checkdas_program_err_count()for errors.das_program_compile_policies(file, access, tout, libgroup, policies)Same as above but applies custom
CodeOfPolicies.das_program_release(program)Frees a compiled program.
das_program_err_count(program)Returns the number of errors (0 = success).
das_program_context_stack_size(program)Returns the minimum stack size for simulation.
das_program_get_error(program, index)Returns the i-th error object.
See tutorial_integration_c_hello_world.
4.3.5.1. Compilation policies
das_policies * pol = das_policies_make();
das_policies_set_bool(pol, DAS_POLICY_AOT, 1);
das_policies_set_bool(pol, DAS_POLICY_NO_UNSAFE, 1);
das_policies_set_int(pol, DAS_POLICY_STACK, 65536);
das_program * prog = das_program_compile_policies(
"script.das", fAccess, tout, lib, pol);
das_policies_release(pol);
Boolean policies (das_bool_policy):
Flag |
Effect |
|---|---|
|
Enable AOT compilation linking |
|
Forbid |
|
Forbid module-level |
|
Forbid heap allocations for globals |
|
Forbid |
|
Treat missing AOT as an error |
|
Enable context mutex for threading |
|
Use string interning |
|
Persistent heap (no GC between calls) |
|
Context-safe code generation |
|
Strict smart pointer rules |
|
Generate extended RTTI |
|
Disable all optimizations |
Integer policies (das_int_policy):
Field |
Effect |
|---|---|
|
Context stack size in bytes |
|
Max heap allocated (0 = unlimited) |
|
Max string heap allocated (0 = unlimited) |
|
Initial heap size hint |
|
Initial string heap size hint |
See tutorial_integration_c_sandbox.
4.3.6. Simulation and context
das_context * ctx = das_context_make(
das_program_context_stack_size(program));
das_program_simulate(program, ctx, tout);
das_function * fn = das_context_find_function(ctx, "main");
das_context_eval_with_catch(ctx, fn, NULL);
das_context_release(ctx);
das_context_make(stackSize)Creates an execution context.
das_program_simulate(program, ctx, tout)Links the program into the context. Returns 1 on success.
das_context_find_function(ctx, name)Finds an exported function by name.
das_context_release(ctx)Frees a context.
See tutorial_integration_c_calling_functions.
4.3.7. Function evaluation
Three calling conventions are provided:
4.3.7.1. Aligned (vec4f)
Arguments and return values use 16-byte aligned vec4f:
vec4f args[2];
args[0] = das_result_int(10);
args[1] = das_result_int(20);
vec4f result = das_context_eval_with_catch(ctx, fn, args);
int sum = das_argument_int(result);
4.3.7.2. Unaligned (vec4f_unaligned)
No alignment requirement — preferred for plain C:
vec4f_unaligned args[2], result;
das_result_int_unaligned(&args[0], 10);
das_result_int_unaligned(&args[1], 20);
das_context_eval_with_catch_unaligned(ctx, fn, args, 2, &result);
int sum = das_argument_int_unaligned(&result);
4.3.7.3. Complex results (cmres)
For functions returning structures or tuples:
MyStruct result_buf;
das_context_eval_with_catch_cmres(ctx, fn, args, &result_buf);
The caller allocates the buffer; the function writes the result into it.
4.3.8. Argument helpers
Extracting values from vec4f (in interop functions):
das_argument_int(arg), das_argument_uint(arg),
das_argument_int64(arg), das_argument_uint64(arg),
das_argument_bool(arg), das_argument_float(arg),
das_argument_double(arg), das_argument_string(arg),
das_argument_ptr(arg), das_argument_function(arg),
das_argument_lambda(arg), das_argument_block(arg)
Packing values into vec4f (for returning from interop functions):
das_result_void(), das_result_int(r), das_result_uint(r),
das_result_int64(r), das_result_uint64(r),
das_result_bool(r), das_result_float(r),
das_result_double(r), das_result_string(r),
das_result_ptr(r), das_result_function(r),
das_result_lambda(r), das_result_block(r)
Unaligned variants (_unaligned suffix) take a vec4f_unaligned *
argument instead.
4.3.9. Calling lambdas and blocks
Lambdas and blocks use parallel evaluation functions:
// Lambda (heap-allocated closure)
das_context_eval_lambda(ctx, lambda, args);
das_context_eval_lambda_unaligned(ctx, lambda, args, nargs, &result);
// Block (stack-allocated closure)
das_context_eval_block(ctx, block, args);
das_context_eval_block_unaligned(ctx, block, args, nargs, &result);
Complex-result variants (_cmres) are also available.
See tutorial_integration_c_callbacks.
4.3.10. Binding C functions
vec4f my_add(das_context * ctx, das_node * node, vec4f * args) {
int a = das_argument_int(args[0]);
int b = das_argument_int(args[1]);
return das_result_int(a + b);
}
das_module * mod = das_module_create("my_module");
das_module_bind_interop_function(mod, lib, my_add,
"add", "my_add", SIDEEFFECTS_none, " Cii>i");
The args string uses daslang’s type mangling format.
For unaligned calling convention:
void my_add_u(das_context * ctx, das_node * node,
vec4f_unaligned * args, vec4f_unaligned * result) {
int a = das_argument_int_unaligned(&args[0]);
int b = das_argument_int_unaligned(&args[1]);
das_result_int_unaligned(result, a + b);
}
das_module_bind_interop_function_unaligned(mod, lib, my_add_u,
"add", "my_add_u", SIDEEFFECTS_none, " Cii>i");
See tutorial_integration_c_binding_types.
4.3.11. Binding types
4.3.11.1. Structures
das_structure * st = das_structure_make(lib,
"MyType", "MyType", sizeof(MyType), alignof(MyType));
das_structure_add_field(st, mod, lib,
"x", "x", offsetof(MyType, x), "f"); // float
das_structure_add_field(st, mod, lib,
"y", "y", offsetof(MyType, y), "f"); // float
das_module_bind_structure(mod, st);
Field types use mangled-name format ("f" = float, "i" = int,
"s" = string, etc.).
4.3.11.2. Enumerations
das_enumeration * en = das_enumeration_make(
"Color", "Color", 0);
das_enumeration_add_value(en, "red", "Color::red", 0);
das_enumeration_add_value(en, "green", "Color::green", 1);
das_enumeration_add_value(en, "blue", "Color::blue", 2);
das_module_bind_enumeration(mod, en);
4.3.11.3. Type aliases
das_module_bind_alias(mod, lib, "Color", "i"); // alias Color = int
4.3.12. String allocation
char * s = das_allocate_string(ctx, "hello");
Allocates a copy on the context’s string heap. The returned pointer is managed by the context — do not free it manually.
4.3.13. Context variables
After simulation, global variables are accessible by name or index:
int idx = das_context_find_variable(ctx, "counter");
if (idx >= 0) {
int * ptr = (int *)das_context_get_variable(ctx, idx);
*ptr = 42; // direct memory write
}
int total = das_context_get_total_variables(ctx);
for (int i = 0; i < total; i++) {
printf("%s: %d bytes\n",
das_context_get_variable_name(ctx, i),
das_context_get_variable_size(ctx, i));
}
See tutorial_integration_c_context_variables.
4.3.14. Serialization
// Serialize
const void * data;
int64_t size;
das_serialized_data * blob = das_program_serialize(
program, &data, &size);
// Save data/size to file...
// Deserialize (skips parsing and type inference)
das_program * restored = das_program_deserialize(data, size);
// Clean up
das_serialized_data_release(blob);
See tutorial_integration_c_serialization.
4.3.15. AOT checking
das_function * fn = das_context_find_function(ctx, "test");
if (das_function_is_aot(fn)) {
printf("Running as native AOT code\n");
}
See tutorial_integration_c_aot.
4.3.16. Module groups
das_module_group * lib = das_modulegroup_make();
das_module * mod = das_module_create("my_module");
// ... bind functions, types, enums ...
das_modulegroup_add_module(lib, mod);
das_program * prog = das_program_compile(
"script.das", fAccess, tout, lib);
das_modulegroup_release(lib);
4.3.17. Side effects
Side-effect constants for das_module_bind_interop_function:
SIDEEFFECTS_nonePure function.
SIDEEFFECTS_unsafeFunction is unsafe.
SIDEEFFECTS_modifyExternalModifies external state (stdout, files).
SIDEEFFECTS_accessExternalReads external state.
SIDEEFFECTS_modifyArgumentMutates a reference argument.
SIDEEFFECTS_modifyArgumentAndExternalBoth modifyArgument and modifyExternal.
SIDEEFFECTS_accessGlobalReads shared global state.
SIDEEFFECTS_invokeCalls daslang callbacks.
SIDEEFFECTS_worstDefaultSafe fallback — assumes all side effects.