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

is it possible to return handlers to complex go structs #7

Open
Licenser opened this issue May 30, 2024 · 4 comments
Open

is it possible to return handlers to complex go structs #7

Licenser opened this issue May 30, 2024 · 4 comments

Comments

@Licenser
Copy link

Hi,

I am wondering if and how it is possible to return complex structures (or points to them more likely) as opaque types from calls.

Say I have a client implemented in go and want to initialize it and then return a handler to the client.

I basically want to do something like this:

struct FancyGoClient {
  client: NonNullPtr<()> // or some other struct
}

impl FancyGoClient {
  fn new(url: &str) -> Self {
    Self{ 
      client: call_to_go_init(url)
    }
  }
  fn do_the_thing(&self) -> u64 {
    call_to_go_do_the_thing(self.client)
  }
}
@ihciah
Copy link
Owner

ihciah commented Jun 3, 2024

In the long run, I plan to split up a bunch of coupled components in this repository, including exposing different ABI interfaces for selection, using interfaces for structure conversion and allowing users to implement them manually, etc.
In the short term, to solve your needs, you can manually implement a wrapper on the golang side to convert the structure again.

@Licenser
Copy link
Author

Licenser commented Jun 3, 2024

Manuall is totally fine, the problem I ran into is that in the rust-side of things I couldn't express "this is a pointer to unknown" as any approach I tried told me parameterized type are a no-no

@furkankly
Copy link

I have the same exact usecase and I can't find a way to express pointers in the FFI boundary.
Tried Box, got Error("custom types with arguments are not supported").
Tried *const got only path type returns are supported.
Tried unsafe usize to pointer conversions on both sides and got incorrect values because of possible wrong memory alignments.

I skimmed the blog post about the library and it felt like this is expected because it explicitly mentions "...As we cannot control the lifetime of the return value Rust side receives (the upper layers might even store it in a global structure), the copy upon being called by FFI on the Rust side is inevitable; Rust performs the copy after being called, allocating its own memory..." somewhere. Does that mean we can't work with raw pointers in the FFI boundary? Do we need to have owned values or smart pointers in the return values of Go functions?

@ihciah
Copy link
Owner

ihciah commented Oct 8, 2024

Does that mean we can't work with raw pointers in the FFI boundary?

Passing pointer as a number is ok now. But passing and managing the object lifetime behind the pointer are 2 different things.

Make a smart pointer and map it to different languages are good, at lease for Rust/C++. However, golang seems haven't provide a destructor ability which can be automatically called when the object is going to be released.

There are another totally different way to do that: since I also provide a shared-memory mode, doing it based on communication will be very easy. Current definition is like:

  1. Caller->Callee: Request
  2. Callee->Caller: Response+RequestReleaseNotify
  3. Caller->Callee: ResponseReleaseNotify
    When passing pointers manually, we can hold the object until receive ResponseReleaseNotify at golang side.

However, now the CGO mode and shared-memory mode are compatiable with each other. If implement it like the former solution, it will only work under shared-memory mode.

To make CGO mode also work, we may add another CGO call for each async call that does not copy response instantly. This will make the project more elegant by making some abstraction with the oneway message passing(it can be a CGO call or shm queue message).

Do you have any idea about it? Or do you have interest implementing it? :)

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

3 participants