dynamic-crystals v0.0.1
Crystal Dynamic C Bindings Demo
This project demonstrates how to use dynamic C bindings in Crystal by loading and calling functions from shared libraries at runtime using dlopen
and dlsym
.
What This Demo Shows
inspired by
https://github.com/fabianloewe/dynamic-library
The project consists of two components:
-
Injector (
injector/
): A Crystal module that defines a C function calledregister
which simply prints "registered". This gets compiled into a shared library (libinjector.so
). -
CLI (
cli/
): A Crystal program that dynamically loads the injector shared library at runtime, finds theregister
function usingdlsym
, and calls it as aProc
.
This demonstrates the power of Crystal's C bindings system - instead of linking libraries at compile time, you can load and call C functions dynamically at runtime.
Building and Running
Prerequisites
- Crystal compiler
- Make
- GCC (for linking the shared library)
Build
# Build everything (injector library + CLI executable)
make
# Or build components individually:
make injector # Builds lib/libinjector.so
make cli # Builds bin/cli
Run
./bin/cli
Expected output:
Pointer(Void)@0x7f... # Address of loaded library
Pointer(Void)@0x7f... # Address of register function
registered # Output from calling the function
Clean
make clean
How It Works
The Injector Library
The injector (injector/src/injector.cr
) defines a simple C function:
fun register : Void
puts "registered"
end
This gets cross-compiled to an object file and linked into a shared library using Crystal's --cross-compile
flag.
The CLI Application
The CLI (cli/src/cli.cr
) demonstrates dynamic loading:
- Load Library: Uses
dlopen()
to loadlibinjector.so
at runtime - Find Symbol: Uses
dlsym()
to find theregister
function - Call Function: Converts the function pointer to a Crystal
Proc
and calls it
LibC Bindings
The project includes custom LibC bindings (cli/src/libC/lib_c.cr
) for dynamic loading functions:
dlopen
- Load a shared librarydlsym
- Find a symbol in a loaded librarydlclose
- Close a loaded librarydlerror
- Get error information
Use Cases
Dynamic C bindings are useful for:
- Plugin systems
- Optional dependencies
- Runtime library selection
- Interfacing with system libraries
- Hot-swapping code modules
Project Structure
├── Makefile # Main build file
├── bin/ # Built CLI executable
├── lib/ # Built shared library
├── cli/ # CLI application source
│ ├── src/cli.cr # Main CLI code
│ └── src/libC/lib_c.cr # LibC bindings
└── injector/ # Injector library source
└── src/injector.cr # C function definition
This is a minimal but complete example of Crystal's dynamic C binding capabilities.
dynamic-crystals
- 0
- 0
- 0
- 0
- 0
- 6 days ago
- July 14, 2025
Sun, 20 Jul 2025 13:07:47 GMT