Question: why do you have 2 crates that at least conceptually have cyclic imports, rather than just merging the 2 crates?
I ask because I have a hypothesis that I’m looking to either confirm or falsify: That whenever there is a cyclic dependency in software, it’s nothing more than a strong hint that the components involved should be merged into 1, and after that perhaps re-refactored into a tree-like shape, which is a more natural form for software anyway.
Not quite. The intention of the library is to enable writing plugins for LADSPA hosts in Rust. Since LADSPA is a C API, it would be nice to provide some kind of Rusty wrapper around it.
The plugin host (typically part of a DAW) dynamically loads the library and calls the LADSPA entry point. This entry point is an extern "C" function within ladspa.rs, which then defers to the user’s #[no_mangle] Rust entry point. I need some way of finding the user code so I can execute it when the LADSPA entry point is called. The user’s code cannot register itself at runtime because it would need to do so in some kind of static constructor, which we don’t have in Rust. I wanted to avoid having users implement the C entry point directly so they wouldn’t have to use unsafe code.
Sure, I could use an extern "C" ABI for the user entry point, but why should I have to when it’s Rust calling Rust?
While I see and agree with your point in spirit, I do not know of any currently existing, safe, Rust-specific ABIs that can deal with dynamic linking.
With that in mind, the only real option is the C ABI I think. That said, it’s not that bad, since access through libloading is safe, in the sense that pointers into the dynamic lib are pretty much guaranteed to be valid.
In addition, you get the option of adding code written in other languages and/or by other people, as long as those languages can compile into dynamic libraries. This may not matter to you, but I’m just throwing it out there.
Other than the understandable wish to do better than the C ABI status quo, is there a specific reason for wanting a Rust ABI?