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

generating custom bindings? #1031

Closed
chuckries opened this issue Aug 10, 2021 · 2 comments
Closed

generating custom bindings? #1031

chuckries opened this issue Aug 10, 2021 · 2 comments
Labels
question Further information is requested

Comments

@chuckries
Copy link
Member

I've been playing around with some rust -> windows interop again. I have a method exported from a native windows dll I want to call, but it takes an LPCWSTR. It turns out that this is non trivial to do over rust's FFI boundary (convert String/&str to encoded u16[], terminate with 0, pass over FFI as *const u16, etc.)

I was hoping rust would make this easier but it doesn't look like it. windows-rs can easily generate bindings for things like this in win32 (GetEnvironmentVariableW is the example I looked at). It has solved this with the PWSTR type and the IntoParam defs, etc.

Is there any way to easily leverage this for something not defined in winmd? It'd be nice if I could use some of the binding primitives to make a nice binding for my FFI, but PWSTR is only generated into a bindings file.

Any thoughts?

@riverar
Copy link
Collaborator

riverar commented Aug 11, 2021

@chuckries Hey Chuck. While you could write all the goop for this manually... [[gets closer]] let me show ya something cool. In a PR to the windows-app-rs repo, I've got win32metadata's winmdgenerator all wired up and ready to go. It scrapes some headers/libs I feed it and pops out a winmd that's ready for windows crate consumption. Saves so much time.

If you're interested in trying it out, just grab the .proj file and one of the .cpp files from https://github.com/microsoft/windows-app-rs/tree/73f83e7e5239615ece8080e92c3c13e6add795df/.metadata, fix up the msbuild xml, edit the .cpp (importing your headers as needed), then dotnet build in that folder and the rest should happen automatically. The generator is pretty finicky, so a few tips:

  • the first run may blow up as it dotnet installs some tools, puts .bin into path; restart your shell/app to bring in new env vars
  • if you don't have any import/static libs to scan, use the dummy.lib in that repo
  • make absolutely sure the importlib path has \x64\ in the path; if that doesn't match your layout, don't fret, just cheat the system with a relative path (e.g. \x64\..\ as a no-op)
  • ping me if you get stuck, happy to help (am on Teams too if needed)

@riverar riverar added the question Further information is requested label Aug 11, 2021
@kennykerr
Copy link
Collaborator

Yep, Rafael's suggestion is your best bet today. You can of course produce your own winmd by some other means, but this is probably simpler.

Once #81 is complete, you'll be able to define your own APIs directly in Rust and it will thus be able to generate custom bindings without resorting to external tools.

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

No branches or pull requests

3 participants