I'm newbie in Rust, and trying to compile Rust code into WASM:
use libloading::{Library, Symbol};
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn main() {
// Load the DLL
let lib = unsafe { Library::new("file.dll").unwrap() };
let connect: Symbol<unsafe extern "C" fn(*const std::os::raw::c_char, *const std::os::raw::c_char) -> i32;> =
unsafe { lib.get(b"Function\0").unwrap() };
But when i run wasm-pack i'm getting the error:
error[E0432]: unresolved imports 'libloading::Library', 'libloading::Symbol'
--> src\lib.rs:1:18
|
1 | use libloading::{Library, Symbol};
| ^^^^^^^ ^^^^^^ no 'Symbol' in the root
| |
| no 'Library' in the root
For more information about this error, try 'rustc --explain E0432'`.
error: could not compile 'rust' due to previous error
Error: Compiling your crate to WebAssembly failed
Caused by: failed to execute 'cargo build': exited with exit code: 101
full command: "cargo" "build" "--lib" "--release" "--target" "wasm32-unknown-unknown"`
If my undestanding is right - libloading can'not complie to WASM.
Does any one know way to comple such Rust code into WASM? Or may be there is any other approach to access functions from dll file in JS (React).
I'm trying:
change 'release' in toml file;
compile in binary file;
Related
I have set up a rust base project according to the Getting Started page of the rocket-framework:
I added this line to my Cargo.toml: rocket = "0.4.10"
My main.rs:
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use] extern crate rocket;
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
fn main() {
rocket::ignite().mount("/", routes![index]).launch();
}
When I try to run (or cargo build it) I get the following error:
Compiling rocket v0.4.10 error[E0277]: the trait bound `(dyn handler::Handler + 'static): handler::Handler` is not satisfied --> /Users/.../.cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.4.10/src/rocket.rs:299:41
| 299 | let outcome = route.handler.handle(request, data);
| ^^^^^^ the trait `handler::Handler` is not implemented for `(dyn handler::Handler + 'static)`
For more information about this error, try `rustc --explain E0277`. error: could not compile `rocket` due to previous error
I also tried it with previous versions of the rocket framework, all of them threw the same error.
Of course I'm using the latest nightly version of rust, right before cargo build I entered following commands:
rustup override set nightly
info: using existing install for 'nightly-x86_64-apple-darwin'
info: override toolchain for '/Users/...' set to 'nightly-x86_64-apple-darwin'
nightly-x86_64-apple-darwin unchanged - rustc 1.58.0-nightly (bd41e09da 2021-10-18)
Is there a known issue with the latest rust compiler on MacOS? Is there any other solution I could try?
I have tried to compile nvptx in Rust with the help of this site. Here is the code I wrote.
use std::time::Duration;
use std::thread::sleep;
#[cfg(target_arch="nvptx")]
fn foo() {
println!("call");
use std::arch::nvptx::*;
unsafe {
let c = malloc(10);
sleep(Duration::from_millis(100000));
free(c);
}
}
fn main() {
#[cfg(target_arch="nvptx")]
foo();
println!("Hello, world!");
}
I've done my research.
I thought it might be possible to compile to nvptx by doing cargo run --target nvptx64-nvidia-cuda. However, when I tried to run it, I received the following error.
error[E0463]: can't find crate for `std`.
|.
= note: the `nvptx64-nvidia-cuda` target may not be installed
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
error: could not compile `core_nvptx`.
To learn more, run the command again with --verbose.
So, I set rust to nightly and added a target for nvptx.
rustup target add nvptx64-nvidia-cuda.
So we added
cargo run --target nvptx64-nvidia-cuda.
I received the same error as above when I did
postscript
I have created a separate nvptx crate with the following file structure.
├─ Cargo.lock
├─ Cargo.toml
├─ nvptx
│ ├─ Cargo.lock
│ ├─ Cargo.toml
└─ src
└─ lib.rs
r└─ src
r└─ main.rs
I created a .cargo/config file in the nvptx crate.
In it, I wrote the following
[build].
target = "nvptx64-nvidia-cuda".
And here is how the contents of nvptx/src/lib.rs looks
#! [feature(stdsimd)]
#! [no_std] #!
use core::arch::nvptx;
use core::ffi::c_void;
unsafe fn cuda_alloc(size: usize) -> *mut c_void {
nvptx::malloc(size)
}
unsafe fn cuda_free(ptr: *mut c_void) {
nvptx::free(ptr);
}
Also, the code in src/main.rs is as follows.
use std::time::Duration;
use std::thread::sleep;
use nvptx::*;
fn foo() {
println!("call");
unsafe {
let ptr = cuda_alloc(10 as usize);
cuda_free(ptr);
}
}
fn main() {
foo();
println!("Hello, world!");
}
When I compiled this, I received the following error.
error[E0432]: unresolved import `core::arch::nvptx`
--> nvptx/src/lib.rs:4:5
| use core::arch::nvptx
4 | use core::arch::nvptx;
| ^^^^^^^^^^^^^^^^^ no `nvptx` in `arch`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0432`.
error: could not compile `nvptx`.
To learn more, run the command again with --verbose.
Rust version:
nightly-x86_64-unknown-linux-gnu (default)
rustc 1.54.0-nightly (f94942d84 2021-05-19)
Here is the function lies in huangjj27:env_logger/src/writer/wasm.rs
//! logging functions from wasm-bindgen.
//!
//! Here use the one-param logging functions, all messages should be transformed
//! to string before passing to the functions. Note that we only need this
//! module for `wasm32-unknown-unknown` target
#![cfg(all(target_arch = "wasm32", target_vendor = "unknown"))]
// use log::Level;
use wasm_bindgen::prelude::*;
use crate::fmt::glob::Target;
pub(in crate::fmt::writer) fn print(msg: &str, t: Target) {
// work around for unused variable
let _ = t;
log(&msg);
}
As is shown above, the wasm module will only compile with wasm32-unknown-unknown target. And the print function is used in huangjj27:env_loggersrc\fmt\writer\termcolor\shim_impl.rs:
// huangjj27:env_loggersrc\fmt\writer\termcolor\shim_impl.rs: 32-48
pub(in crate::fmt::writer) fn print(&self, buf: &Buffer) -> io::Result<()> {
// This impl uses the `eprint` and `print` macros
// instead of using the streams directly.
// This is so their output can be captured by `cargo test`
let log = String::from_utf8_lossy(&buf.0);
#[cfg(all(target_arch = "wasm32", target_vendor = "unknown"))]
wasm::print(&log, self.target);
#[cfg(not(all(target_arch = "wasm32", target_vendor = "unknown")))]
match self.target {
Target::Stderr => eprint!("{}", log),
Target::Stdout => print!("{}", log),
}
Ok(())
}
then I test it with the node:
wasm-pack test --node -- --no-default-features --test node
then I get this confusing denied unused issue:
[INFO]: Checking for the Wasm target...
Compiling env_logger v0.8.2 (C:\Users\huangjj27\Documents\codes\env_logger)
error: function is never used: `print`
--> src\fmt\writer\wasm.rs:13:31
|
13 | pub(in crate::fmt::writer) fn print(msg: &str, t: Target) {
| ^^^^^
|
note: lint level defined here
--> src\lib.rs:280:54
|
280 | #![deny(missing_debug_implementations, missing_docs, warnings)]
| ^^^^^^^^
= note: `#[deny(dead_code)]` implied by `#[deny(warnings)]`
error: function is never used: `print`
--> src\fmt\writer\wasm.rs:13:31
|
13 | pub(in crate::fmt::writer) fn print(msg: &str, t: Target) {
| ^^^^^
|
note: lint level defined here
--> src\lib.rs:280:54
|
280 | #![deny(missing_debug_implementations, missing_docs, warnings)]
| ^^^^^^^^
= note: `#[deny(dead_code)]` implied by `#[deny(warnings)]`
error: aborting due to previous error
error: could not compile `env_logger`.
warning: build failed, waiting for other jobs to finish...
error: aborting due to previous error
error: could not compile `env_logger`.
To learn more, run the command again with --verbose.
Error: Compilation of your program failed
Caused by: failed to execute `cargo build`: exited with exit code: 101
full command: "cargo" "build" "--tests" "--target" "wasm32-unknown-unknown"
My questions are:
Why does the warning come out, while I indeed use the function wasm::print somewhere?
How could I deal with this problem? Working around or fixing it is ok (but I still need to keep the lint config enabled).
If you only use a function in other unused functions, then it will still give you the warning. If you want to disable the warning on that one function, you can do that by putting #[allow(dead_code)] on the line before the function header.
Trying to compile following rust code to wasm to make it compatible running with existing js. Trying to return hashmaped value from function.
lib.rs
use wasm_bindgen::prelude::*;
use std::collections::HashMap;
#[wasm_bindgen]
pub fn get_transformed_filters()-> HashMap<i32, i32> {
let mut hm = HashMap::new();
for i in 1..9990000 {
hm.insert(i + i, i * i);
}
return hm
}
Console error after running command wasm-pack build
[INFO]: 🎯 Checking for the Wasm target...
[INFO]: 🌀 Compiling to Wasm...
Compiling hello-wasm v0.1.0 (/Users/mfe/ui/rustService/test-wasm)
error[E0277]: the trait bound `HashMap<i32, i32>: IntoWasmAbi` is not satisfied
--> src/lib.rs:15:1
|
15 | #[wasm_bindgen]
| ^^^^^^^^^^^^^^^ the trait `IntoWasmAbi` is not implemented for `HashMap<i32, i32>`
|
= note: required because of the requirements on the impl of `ReturnWasmAbi` for `HashMap<i32, i32>`
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
error: could not compile `test-wasm`
To learn more, run the command again with --verbose.
Error: Compiling your crate to WebAssembly failed
Caused by: failed to execute `cargo build`: exited with exit code: 101
full command: "cargo" "build" "--lib" "--release" "--target" "wasm32-unknown-unknown"
Is there any way to achieve this ?
It seems like I haven't fully understood Rust's module system yet. I have the following file structure:
module_issue
|_Cargo.toml
|_src
|_main.rs
|_lib.rs
|_bindings
|_mod.rs
This code compiles and runs without issues:
// file: bindings/mod.rs
pub fn say_hello() {
println!("Hello from the bindings module!");
}
// file: lib.rs
mod bindings;
pub fn try_bindings() {
bindings::say_hello();
}
// file: main.rs
use module_issue;
fn main() {
module_issue::try_bindings();
}
However, if I make a sub-module in lib.rs and try to use bindings::say_hello() from there, I get a compiler error. Here's what lib.rs now looks like:
// file: lib.rs
mod bindings;
pub fn try_bindings() {
bindings::say_hello();
}
mod debugging {
pub fn try_bindings_debug() {
bindings::say_hello(); // <- can't find 'bindings' - shouldn't it be in scope?
}
}
and this is the error I get:
error[E0433]: failed to resolve: use of undeclared type or module `bindings`
--> src\lib.rs:10:9
|
10 | bindings::say_hello();
| ^^^^^^^^ use of undeclared type or module `bindings`
error: aborting due to previous error
In lib.rs, I also tried replacing mod bindings; with use crate::bindings;, but that resulted in a different error:
error[E0432]: unresolved import `crate::bindings`
--> src\lib.rs:2:5
|
2 | use crate::bindings;
| ^^^^^^^^^^^^^^^ no `bindings` in the root
error[E0433]: failed to resolve: use of undeclared type or module `bindings`
--> src\lib.rs:10:9
|
10 | bindings::say_hello();
| ^^^^^^^^ use of undeclared type or module `bindings`
error: aborting due to 2 previous errors
My understanding of the module system was as follows: If I bring a module A into the scope of module B, then the public members of A will be accessible in B and all the sub-modules of B. In this case, I bring the bindings module into the scope of the library root. The debugging module is a sub-module of that root, so it should have access to bindings as well. Can you tell me where I went wrong? My priority isn't really to solve the problem, but to understand why this doesn't work.
I'm working on Windows 10, with the following toolchain:
cargo 1.39.0 (1c6ec66d5 2019-09-30)
rustc 1.39.0 (4560ea788 2019-11-04)
If I bring a module A into the scope of module B, then the public members of A will be accessible in B and all the sub-modules of B.
This assertion is incorrect. The scope of each module contains only things defined or used in the module itself, not in its parents.
You can, however, pull items from the parent explicitly:
mod debugging {
use super::bindings; // referring to library root
pub fn try_bindings_debug() {
bindings::say_hello();
}
}
Playground