Taaitaaiger / jlrs

Julia bindings for Rust
MIT License
429 stars 21 forks source link

Calling Rust functions without export #110

Closed ShalokShalom closed 1 year ago

ShalokShalom commented 1 year ago

Hi there :)

I assume this comes as a natural conclusion out of your extensive documentation, but I just wanted to be sure:

There is no way to call a Rust function, if it's not specifically exported? I want to call Rust functions, without having to modify the Rust code at all.

ShalokShalom commented 1 year ago

It seems others also perceive your library to require manual rewrites, and you answered in this case, that it's not needed to rewrite Rust, but to setup extern C functions.

I am confused by this, since this seems contradictory.

In order to call that function, I need to set it up in Rust.

You further say, that making that superfluous, makes no sense, since Rusts ABI is unstable. But isn't it exactly Rusts C ABI, that is the only stable one that Rust has?

My background is, that I want to write a GUI on top of Helix, the Rust written editor.

I don't think I will setup C functions for every single call, as this seems like a pretty daunting endeavor anyway.

Thanks a lot for your help and this work :)

Taaitaaiger commented 1 year ago

I don't entirely understand what you mean. The main reason that the example in the readme is written as it is, is to illustrate that call_me can be called from Julia using ccall. You could call_me is a separate crate, compile it as a cdylib, and use that library from Julia, jlrs is not needed.

If a crate already has a C API, it's likely you can simply build a shared library and use it directly without writing any glue code in Rust. This is the case with rsvg: https://github.com/lobingera/Rsvg.jl/blob/master/src/calls.jl

If it doesn´t, you will have to write a binding library in Rust. A lot of glue code (both Rust and Julia) can be generated by using the julia_module macro: https://docs.rs/jlrs-macros/latest/jlrs_macros/macro.julia_module.html. I've used that approach to make RustFFT available in Julia: https://github.com/Taaitaaiger/rustfft-jl/blob/main/src/lib.rs

ShalokShalom commented 1 year ago

To be honest, I think you could possibly overrate the capacity of some potential users. I would like to help you, to provide documentation for such folks. I think you take for granted, that some people enact about a certain kind of competency, that is at least in my case surely not provided.

Particularly, I think not every Julia user has ever called a library like that, and I feel very much overwhelmed by this.

You could call_me is a separate crate, compile it as a cdylib, and use that library from Julia, jlrs is not needed.

That seems undocumented, yes?

If a crate already has a C API, it's likely you can simply build a shared library and use it directly without writing any glue code in Rust

And this is a second way to call Rust from Julia? Or still that first one you mentioned?

The part with writing a binding library is out of my scope anyway, as somebody who is not yet ready to code anything in Rust. I assume this part is still not documented also?

I would like to help with feedback, and whatever else I can provide, to help document that use cases.

If you are comfortable with that. 👍🏻

Taaitaaiger commented 1 year ago

To be honest, I think you could possibly overrate the capacity of some potential users. I would like to help you, to provide documentation for such folks. I think you take for granted, that some people enact about a certain kind of competency, that is at least in my case surely not provided.

Particularly, I think not every Julia user has ever called a library like that, and I feel very much overwhelmed by this.

You could call_me is a separate crate, compile it as a cdylib, and use that library from Julia, jlrs is not needed.

That seems undocumented, yes?

It's documented (or more truthfully, mentioned), right after the example you linked in the issue. I don't think it's the responsibility of jlrs's documentation to explain what a cdylib is, but rather that such info is something that belongs in a tutorial. I've been working on that, but I have to admit progress is slow (and I consider calling Rust from Julia the most advanced topic in jlrs so it won't be covered until the later tutorials).

I'd appreciate your thoughts on what you think is missing in the docs and how it could be improved.

If a crate already has a C API, it's likely you can simply build a shared library and use it directly without writing any glue code in Rust

And this is a second way to call Rust from Julia? Or still that first one you mentioned?

It's the same way, really. If the crate has a C API, Julia can load the library at runtime and find functions defined in it. In the other case no C API exists so another library that provides these entrypoints is necessary.

The part with writing a binding library is out of my scope anyway, as somebody who is not yet ready to code anything in Rust. I assume this part is still not documented also?

There's no guide-level explanation, RustFFT.jl and rustfft-jl are intended as examples.

I'm going to be blunt, but if this is your first time writing Rust code you've picked a very challenging project to work on. FFI in general is quite challenging and requires familiarity with both languages. I'm very open to improving documentation, but I don't think jlrs can be a beginner-friendly library.

I would like to help with feedback, and whatever else I can provide, to help document that use cases.

If you are comfortable with that. 👍🏻

I'd welcome it!

ShalokShalom commented 1 year ago

Yeah, seems like I underestimated the effort that goes into something like that. I expected to just call functions similar to pycall. But you have specified in the Reddit post, that you think the Rust ABI is too unstable. Do you mean the C ABI, or something else?