I was thinking about how Redis supports loading .so
files at runtime and wondering if there’s a way to do something similar in Crystal.
If it requires them being written in Crystal, that’s probably okay, but since Crystal can interface with C pretty nicely I imagine if it’s possible at all it can be done both ways.
1 Like
You can use libdl
to load shared libraries at runtime. It is usually available as part of libc and Crystal’s stdlib C bindings have definitions for the most common functions.
Note: This doesn’t work with binaries statically linked against musl libc because the library is not available in that mode.
With loading done, there are two main ways to actually use a library.
For full flexibility you can use libffi
to define bindings at runtime. That’s what we’re using for Crystal’s interpreter implementation, for example. So there is a FFI implementation available in the compiler code (crystal/src/compiler/crystal/ffi at master · crystal-lang/crystal · GitHub), but it’s closely tied to the interpreter’s needs and won’t work generically. It can serve as a basis for a more generic implementation.
If you know the symbols exposed in the library at compile time, you can skip FFI and make function calls directly with a hard coded call interface. Example: Call a function in a shared library - Rosetta Code
This works well for loading optional dependencies, for example. When available, the lib get’s loaded and used, and if not, the program still works without it.
3 Likes
This is fantastic! Thanks!