I’ve spent some time recently trying to figure out how to dynamically load Rust plugins in my Rust app as shared libraries, but couldn’t find exactly what I was looking for, so I created a tutorial as I worked through figuring it out. Hope this can help anybody looking for the same thing!
Great work. That’s an extensive tutorial!
Unfortunately I found that dynamic linking doesn’t actually work in Rust across different versions of Rust, and the technique for plugins also failed, even inside the same version of Rust, when I tried to compile an app with other dependencies like Amethyst. That leaves the technique outlined in the tutorial not very practical for real applications.
The closest thing I’ve found to accomplish something similar is this project:
AFAICT, the only real option (today, and sounds like for quite a while into the future) is producing
cdylib (ie shared lib) exposing a C ABI, and loading those shared libs as plugins. From a quick skim of your tutorial, it looks like you mention this.
Perhaps there can be a Rust layer/adapter, on top of the raw shared lib/C ABI, that provides a more Rust-like API, but ultimately the C ABI is the only stable/portable one in this regard.
Another option of course is IPC - host plugins in their own (Rust) process, and communicate over some IPC channel. This has its own pros and cons.
That’s pretty much the conclusion I came to. Thankfully I meant to use the setup for the Amethyst game engine, and they are already working on a scripting setup for it through a C FFI so at least I’m not completely shutdown for my use-case.
Would it be an option for you to use Webassembly here?
(Btw typo … PR submitted)
got a new star
You mean for plugins? It could very well be possible. It wouldn’t be exactly the same workflow, but I’ve considered using Wasmtime or CraneLift, which Wasmtime is built on, to Run WASM modules as plugins.
For now I’m going to focus on looking into Amethyst’s scripting plan because that is what I was investigating plugins for.