rust-bindgen icon indicating copy to clipboard operation
rust-bindgen copied to clipboard

Dynamic Linking Support (windows-msvc)

Open wesleywiser opened this issue 2 years ago • 1 comments

When using bindgen on Windows, it is important to know if the library being linked with dynamically or statically as exported global variables from a DLL need their corresponding import declarations marked dllimport. When using __declspec(dllexport) on the variable declaration, bindgen correctly marks the import declaration with #[link(name = "...")] which causes rustc to mark any variables as dllimport.

However, many Windows native libraries do not use __declspec(dllexport) and use module definition files instead. In this case, bindgen does not know to mark the import declarations with #[link(name = "...")] as required and this typically results in obtuse linker errors such as:

  = note: bindgen_repro.2pvcn21dyln8dfar.rcgu.o : error LNK2019: unresolved external symbol SomeVariable referenced in function _ZN13bindgen_repro4main17h30f7fdf053f3b91dE
          target\debug\deps\bindgen_repro.exe : fatal error LNK1120: 1 unresolved externals      

I've assembled a complete reproducer here which demonstrates this: https://github.com/wesleywiser/bindgen-windows-dll-repro

In order to handle libraries that use module definition files, some kind of configuration option probably needs to be added to bindgen to allow the user to force generation of the #[link] attributes.

In searching the issue list, I found #1974 which is similar but asks for examples where the status quo does not work. This is such a case 🙂

Actual Results

/* automatically generated by rust-bindgen 0.65.1 */

extern "C" {
    pub static mut SomeVariable: ::std::os::raw::c_int;
}

Expected Results

/* automatically generated by rust-bindgen 0.65.1 */

#[link(name = "example")]
extern "C" {
    pub static mut SomeVariable: ::std::os::raw::c_int;
}

wesleywiser avatar Jun 08 '23 20:06 wesleywiser

Hey! Thanks for the report!

I don't have a windows machine so I don't have any actual way to fix + test this right now. I'd be happy to review or try to mentor anyone who wants to fix this.

Out of curiosity, I saw that you can pass -Wl"/DEF:my_def_file.def" to clang, does that changes anything if you pass this as a clang-arg to bindgen?

Otherwise, I'd imagine we'd have to either find or come up with a .def file parser and do that logic ourselves.

pvdrz avatar Jun 09 '23 11:06 pvdrz