Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exporting same Foreign Type in two different Libraries #134

Open
ju6ge opened this issue Jun 20, 2024 · 3 comments
Open

Exporting same Foreign Type in two different Libraries #134

ju6ge opened this issue Jun 20, 2024 · 3 comments

Comments

@ju6ge
Copy link

ju6ge commented Jun 20, 2024

Consider the following Situation:

I have a rust-crate and corresponding JuliaPackage that use jlrs lets call this package jlrs-foo it exports an OpaqueType.

crate julia-package
jlrs-foo JlrsFoo
just-type julia-type
jlrs_foo::Foo JlrsFoo.Foo

Now there is a second jlrs Package that depends on jlrs-foo, it has its own types, but also wants to have some function that actually return the type Foo from jlrs-foo. Lets call this package jlrs-bar

Here is what I have tried jlrs-bar/src/lib.rs:

use jlrs::prelude::*;
use jlrs_foo::Foo;

julia_module! {
    struct Foo;
    
    fn get_foo() -> TypedValueRet<Foo> as jlrsbar_get_foo();
}

But this leads to the situation that I now have two forein types that are from rusts perspective the same type, but not from Julias perspective:

just-type julia-type
jlrs_foo::Foo JlrsFoo.Foo
jlrs_foo:Foo JlrsBar.Foo

Since Julia is strongly typed I can not just convert one into the other. I have tried to do that a few different ways, always ending up in a julia error. This is annoying, because I can not just use the value of jlrsbar_get_foo like and other value of type Foo when it is constructed in JlrsFoo.

I have also tried not exporting the type in jlrs-bar and instead try to return ValueRet instead of TypedValueRef<Foo>, but this just leads me down into core dump situations.

Any Ideas how to solve/deal with this Situation?

@Taaitaaiger
Copy link
Owner

That's not possible yet, unfortunately. The main challenge I see is that it can't be truly guaranteed they'll be the same types on the Rust side either; even if they both use the same version of a crate, the libraries can be built with different versions of Rust which can cause issues due to ABI incompatibilities.

I'm not sure what the best solution is. For now I would recommend either writing a single library, or sticking with extern "C" functions and fully repr(C) types if you really need to share them between different libraries.

@ju6ge
Copy link
Author

ju6ge commented Jun 24, 2024

Hm that is indeed sad. But this is a hard problem. Regarding the different Rust versions problem, wouldn't requiring repr(C) for all exported types solve this problem? Then the rust version should not matter for the binary structure of the type that is being exported? Using compatible versions of the crates is still on the user then.

Anyway I will try to avoid this situation for now using a different approach, sticking to only one crate is not an option. So I will need to do some sort of serialization/deserialization.

@Taaitaaiger
Copy link
Owner

Yeah, I was thinking along similar lines. The main issue I see is that every exposed type would need to be repr(C), and the entire public API extern "C". It would not be possible to write a repr(C) newtype wrapper around Vec, for example, and access that array from independent libraries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants