Michael-F-Bryan / rust-ffi-guide

A guide for doing FFI using Rust
https://michael-f-bryan.github.io/rust-ffi-guide/
Creative Commons Zero v1.0 Universal
282 stars 18 forks source link

Plugin system is not supported within the rust ecosystem itself #79

Closed sidgilles closed 4 years ago

sidgilles commented 4 years ago

I was glad to find your article and applied it in my project. However, this does not work when passing structures around dynamic libraries.

For now, it sounds to me that the use case is only for foreign languages with only canonical structures around that.

See https://github.com/rust-lang/rust/issues/67179 and so https://github.com/rust-lang/rust/pull/63338 with this https://github.com/rust-lang/rust/pull/63338#issuecomment-519122090

Do you have any workaround for this, please ? Thanks!

Michael-F-Bryan commented 4 years ago

What exactly do you mean by "does not work"?

sidgilles commented 4 years ago

I mean : the work exposed in your guide work well. But using this for a full modular rust only plugin system will not work that well : passing Rust structures form and to dynamic libs lead to undefined behavior because of the use of static references in various points in the std library.

My small code here put a light on this https://github.com/rust-lang/rust/issues/67179 and it seems that this issue will not be addressed soon https://github.com/rust-lang/rust/pull/63338#issuecomment-519122090

Michael-F-Bryan commented 4 years ago

Ah I think I need to make it clearer that when working with dynamic libraries you are constrained to a C-style API. It doesn't mean you can't use this pattern for dynamically loading Rust code, just that there are extra constraints on the interface between the host and plugin.

For example, instead of the plugin passing a BTreeMap to the host, the host could provide the plugin with a callback, then the plugin executes that callback for each key-value pair in the map. That way the host can allocate a BTreeMap using its own copy of liballoc and you make sure no "complex" types are passed between plugins.

It's annoying, but considering Rust doesn't yet have a stable ABI or linkage story that's probably the best we can do :disappointed:

sidgilles commented 4 years ago

Yes, i understood what you mean. It is a way to explore. For my case, my plan was to transfer a complex structure embedding crossbeam::channel, because of multi-threading around. This is a total rethinking of the project so i will freeze things as it is.

However, yes, it would be nice to make this strong particularity more clearer in your guide.

Rust has a strong future, i believe. This kind of problems will have their solutions in time. Wait and see...