.so on Linux, .dll on Windows) at runtime, allowing you to extend the engine with custom C/C++ code without modifying the core codebase.
Overview
The dynamic library system enables you to:- Write performance-critical code in C/C++
- Integrate existing C libraries into your Talon project
- Extend Talon’s functionality without rebuilding the engine
- Call native functions directly from Wren scripts
Creating a Dynamic Library
1. Write Your C Function
Create a C file (e.g.,add.c) with functions that follow the Wren VM calling convention:
examples/extend/add.c
All foreign functions must:
- Take a single
WrenVM*parameter - Use
callconv(.c)calling convention - Return
void - Interact with Wren through slot-based API
2. Build the Shared Library
Use Zig’s build system to compile your C code into a shared library:examples/extend/build.zig
add.dllon Windowslibadd.soon Linuxlibadd.dylibon macOS
Using Dynamic Libraries in Wren
1. Load the Library
Use theembed module to register foreign functions:
examples/extend/game.wren
"C.add(_,_)"- The Wren signature (class.method with arity)"add.dll"- Path to the shared library"wren_c_embed_add"- The C function name to bind
2. Call the Function
Once registered, use it like any other Wren method:examples/extend/main.wren
Wren Slot API Reference
When writing C functions for Talon, use these Wren API functions:Getting Values from Wren
Returning Values to Wren
Slot 0 is reserved for the return value. Arguments start at slot 1.
Platform-Specific Implementation
Talon handles platform differences automatically: Windows (src/common.zig:118-136):
src/common.zig:142):
Complete Example
See the full working example in the source tree:- C source:
examples/extend/add.c - Build script:
examples/extend/build.zig - Wren loader:
examples/extend/game.wren - Usage:
examples/extend/main.wren
Advanced Use Cases
Passing Complex Types
For structs and complex types, use foreign classes:Error Handling
Always check that:- The library file is in the correct location
- Function names match exactly (C name mangling)
- The library is compiled for the target platform
Performance Considerations
- Dynamic loading overhead is minimal (one-time at startup)
- Function calls have the same performance as built-in bindings
- No runtime penalty after initial load
- Consider dynamic libraries for:
- CPU-intensive algorithms
- Existing C/C++ codebases
- Platform-specific functionality
Next Steps
Custom Bindings
Learn how to add permanent Raylib bindings
Build System
Configure Zig build scripts for your project