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

Error 126 while loadind DLL compiled by Rust on Windows #33842

Closed
dancing-in-the-air opened this issue May 24, 2016 · 8 comments
Closed

Error 126 while loadind DLL compiled by Rust on Windows #33842

dancing-in-the-air opened this issue May 24, 2016 · 8 comments
Labels
O-windows Operating system: Windows

Comments

@dancing-in-the-air
Copy link

Loading DLL compiled by Rust 1.8.0 on Windows 10 x64 results in error 126.

lib.rs as simple as follow:

use std::fs::File;
use std::io::Write;

#[no_mangle]
pub extern fn test_dll_call() -> u8 {
    let mut f = File::create("C:\\test.txt").unwrap();
    f.write(b"Hello, world!").unwrap();
    return 0
}

Cargo.toml

[package]
name = "test"
version = "0.1.0"
authors = ["user"]

[lib]
name = "test"
crate-type = ["dylib"]

[dependencies]


[profile.release]
opt-level = 3
debug = false
rpath = false
lto = false
debug-assertions = false
codegen-units = 1

It's built by simple cargo build --release

rustc --version --verbose

rustc 1.8.0 (db2939409 2016-04-11)
binary: rustc
commit-hash: db2939409db26ab4904372c82492cd3488e4c44e
commit-date: 2016-04-11
host: i686-pc-windows-msvc
release: 1.8.0

As a result DependencyWalker shows a lot of API-MS-W1IN-CORE-* DLLs missing in my system for the compiled DLL:
API-MS-WIN-CORE-APIQUERY-L1-1-0.DLL
API-MS-WIN-CORE-APPCOMPAT-L1-1-1.DLL
API-MS-WIN-CORE-APPINIT-L1-1-0.DLL
API-MS-WIN-CORE-ATOMS-L1-1-0.DLL
...

However on my Windows 10 x64 system I've already installed MS Visual Studio 2015 and MS C++ Redistributables 2005, 2010, 2012, 2013 and 2015.

I've picked up errors during the DLL loading by ProcessMonitor. I'm confused by missing 整瑳搮汬.DLL.

How can I help to solve this problem?

@alexcrichton
Copy link
Member

Could you also provide details about how you're linking the DLL into an executable and running it?

@dancing-in-the-air
Copy link
Author

I've created simple C++ program to test this case:

#include <stdio.h>
#include <windows.h>

int main() {
    HMODULE hLibrary = LoadLibrary((LPCWSTR)"test.dll");
    if (hLibrary == NULL) {
        printf("Error while importing DLL: %lu\n", GetLastError());
        return 1;
    }

    return 0;
}

Also I've tried to load it into Lua script:

require("test");

function main()
    test.test_dll_call();
end

However the error is laconic: "loop or previous error loading module 'test'".

@alexcrichton
Copy link
Member

In C++ it looks like that may be an error as "test.dll" can't be cast to a wide string (LPCWSTR), right? That'd cause it to be decoded as utf-16 which may explain the unusual characters?

In Lua I'm not really sure what the error would be though

@JeremySorensen
Copy link
Contributor

Yeah, it should be HMODULE hLibrary = LoadLibrary(L"test.dll");in C(++)

@steveklabnik steveklabnik added the O-windows Operating system: Windows label May 24, 2016
@retep998
Copy link
Member

retep998 commented May 25, 2016

Dependency Walker will always complain about those API dlls, but they're perfectly fine. Don't mind them, it's just how newer versions of Windows handle system APIs and Dependency Walker doesn't understand them.

Anyway, I just tested creating a Rust DLL and was able to both link against it at link time, as well as dynamically load it using LoadLibrary using a simple C++ program. So apparently "test.dll", if reinterpreted as UTF-16, is in fact "整瑳搮汬", so if you just fix your LoadLibrary call (I recommend explicitly using the W version LoadLibraryW(L"test.dll")) everything should be fine. Totally not Rust's fault here.

Also if you update to the latest nightly you can use the new cdylib crate type instead of dylib which is much better for creating Rust DLLs intended to be consumed by other languages as it doesn't include a ton of metadata junk.

@dancing-in-the-air
Copy link
Author

Yeah, shame on me: wide string must be used in C++. With it DLL loads flawlessly. Thank you!
In Lua error still occurs but it seems not Rust problem.

Unfortunately nightly x86 Rust doesn't compile DLL with crate cdylib:

cargo build --release
warning: crate-type "cdylib" was not one of lib|rlib|dylib|staticlib
error: cannot compile `test v0.1.0 (file:///C:/data/projects/test)` as the target `i686-pc-windows-msvc` does not support any of the output crate types

Could you give me the cue is there any information about new crate types?

@alexcrichton
Copy link
Member

Ah no worries! The cargo support for cdylib is coming in rust-lang/cargo#2741, but otherwise it sounds like we're all good here, so I'm gonna close.

@silverweed
Copy link

silverweed commented Feb 14, 2020

I'm having the same issue here. This is my project which has 3 crates: one static lib, one dynamic lib (cdylib) and an executable.
The dynamic lib (ecs_game) depends on the static lib (ecs_engine) and gets compiled into a single DLL. The executable (ecs_runner) then loads the DLL dynamically (I'm using the libloading crate for that).
Here is what happens:

  • on Linux/Mac, the lib gets loaded just fine
  • on an old (pre-anniversary update) Windows, it gets loaded just fine
  • on newer Windows installations, it fails with error 126.

I also tried to create a small C program that uses LoadLibraryA directly to load the library and it gives the same exact error.
Am I doing something wrong here?

(this is the C loader:)

#include <windows.h>
#include <stdio.h>

int main() {
	HMODULE lib = LoadLibraryA("ecsde/target/release/ecs_game.dll");
	if (lib) {
		printf("Hurray!\n");
	} else {
		DWORD last_err = GetLastError();
		printf("Failed to load. Last err = %d\n", last_err);
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-windows Operating system: Windows
Projects
None yet
Development

No branches or pull requests

6 participants