Hi there,
I’m trying to do some native windows rust programming. I’m using native-windows-gui and native-windows-derive to do it, but if I try to mix that with tokio, I get the following:
No entry point found error for GetWindowSubclass. On console, I get:
error: process didn't exit successfully: `C:\source\myprojectanem\target\debug\myprojectname.exe` (exit code: 0xc0000139, STATUS_ENTRYPOINT_NOT_FOUND)
If I change
#[tokio::main]
async fn main() {
to:
fn main() {
The problem goes away, but obviously I can’t use tokio then.
Any clue what the problem is and how to fix it?
Apparently the problem is due to an incompatibility between the use of certain libraries (winapi and windows-sys) which use different versions of COM. At least so I deduce from the documentation I’ve read.
There’s a workaaround:
On Cargo.toml, use.
[build-dependencies] embed-manifest = "1.3.1"
And on the root of the project (not the src dir) create a build.rs file with the following content:
use embed_manifest::{embed_manifest, new_manifest}; fn main() { if std::env::var_os("CARGO_CFG_WINDOWS").is_some() { embed_manifest(new_manifest("Contoso.Sample")).expect("unable to embed manifest file"); } println!("cargo:rerun-if-changed=build.rs"); }
This embeds a manifest together with the executable, solving the issue.
wouldn’t it be better to use
instead of checking an env variable?
Reference: https://doc.rust-lang.org/rust-by-example/attribute/cfg.html
Possibly yes. I’ll check if the results are equivalent.
You can manually convert a
tokio::main
to a regularmain
by constructing a tokio runtime and telling it to block on a top-level future (e.g. an async block).https://tokio.rs/tokio/tutorial/hello-tokio
That will at least help you break down the problem to locate the issue.
I don’t know anything about Windows though. Maybe there’s some per-thread setup that needs to be done in tokio’s thread pool?
Same erro by using this approach.
Tokio works fine, by itself. windows-native-gui works fine, by itself. It is the combination that causes this issue.