How call functions from DLL?


#1

DLL is written in C. Especially standard Windows library as user32, kernel32 or gdi32.


#2

Specifically for the Windows API you’ll want to use the winapi crate.

For other cases, see the FFI section of the Rust book.


#3

you can use rust_libloading


#4

I want use winapi-rs crate in my program/library. Is any small caller example for winapi-rs?


#5

winapi has a small example in its readme right here.

There are also plenty of crates that depend on winapi which you can look at for inspiration.


#6

I just wrote up a chapter on dynamic loading for my FFI tutorial. If you want more of a walkthrough then check that out.

Let me know if there’s anything which could be improved or needs changing, it’s still very much a work in progress so any input would be appreciated.


#7

I’m having similar issue. I’ve got a Windows dll ATSLib.dll exporting init() function.

I’m trying to use it like this

#[link(name = "ATSLib.dll"]
extern {
  fn init();
}

When I compile it I get error: linking with link.exe failed: exit code: 1181 and then later on note: LINK : fatal error LNK1181: cannot open input file ATSLib.dll.lib.

I suppose I’m also missing something on my Cargo.toml.
Also, do I need to link to the specific location of the dll file? On the server this will somewhere else.

I must admit I’ve never really used Windows before so I might miss very basic concepts.

Thanks!

-Marco


#8

You cannot link to DLLs directly. You need to have an import library that you can link against. With your DLL are there any files that have a .lib extension? If so, you’ll likely need to link against that. If not, you’ll have to use dumpbin.exe to get the list of exports from the DLL to manually create a .def file to turn into a .lib using lib.exe.


#9

Thanks a lot! Great suggestions. I’ve got the lib file. Now what?

Will #[link(name = "ATSLib"] work?
Does the lib/dll fine need to specified fully? (like C:\...\ATSLib.lib)


#10

If the library is named ATSLib.lib then #[link(name = "ATSLib"] is correct. Do not name the full path to the library, just the name of the file itself. To specify where the library is, you’d have to use either a build script, or just abuse the fact that you’re using the msvc toolchain and add the folder C:\...\ to your LIB environment variable (semicolon separated list of absolute paths).


#11

Thanks so much! Now compilation works flawlessly. When I move the executable onto the windows machine it should run on I get missing VCRUNTIME140.dll. I’m guessing I need to install some Visual Studio stuff over there as well.


#12

You’ll need to either install the appropriate VC++ redistributable or use the new -Ctarget-feature=+crt-static rustc flag to link to the CRT statically. If you use the latter option you’ll need to set that flag via your cargo configuration which is not the same as Cargo.toml.


#13

Great! I’ll try this as soon as I’m back in my office.