Closed
Description
Hi,
I'm trying to write some Rust "Hello, World!" code that can be shared between C and JavaScript. My project lives here. The C part is working, but I'm having some trouble getting the JavaScript part working. I'm following the "Basic Usage" example in this repo, the console.log example in this repo, and this example for calling Rust from C.
My first attempt used cfg
to conditionally compile the necessary code, but it failed with
TypeError: wasm.__wbindgen_global_argument_ptr is not a function
src/lib.rs
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
#[cfg(target_arch = "wasm32")]
extern crate wasm_bindgen;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
extern {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub fn greet(name: &str) {
do_greet(name);
}
#[cfg(not(target_arch = "wasm32"))]
extern crate libc;
#[cfg(not(target_arch = "wasm32"))]
use std::ffi::CStr;
#[cfg(not(target_arch = "wasm32"))]
use libc::c_char;
#[cfg(not(target_arch = "wasm32"))]
fn log(str: &str) {
println!("{}", str);
}
#[cfg(not(target_arch = "wasm32"))]
#[no_mangle]
pub extern "C" fn greet(name: *const c_char) {
let c_name = unsafe { CStr::from_ptr(name) };
do_greet(c_name.to_str().unwrap());
}
fn do_greet(name: &str) {
log(&format!("Hello, {}!", name));
}
$ make
cargo build
Compiling unicode-xid v0.1.0
Compiling wasm-bindgen-shared v0.2.0
Compiling serde v1.0.37
Compiling fnv v1.0.6
Compiling dtoa v0.4.2
Compiling num-traits v0.2.2
Compiling itoa v0.4.1
Compiling libc v0.2.40
Compiling cfg-if v0.1.2
Compiling proc-macro2 v0.3.6
Compiling quote v0.5.1
Compiling syn v0.13.1
Compiling serde_json v1.0.13
Compiling serde_derive_internals v0.23.0
Compiling serde_derive v1.0.37
Compiling wasm-bindgen-backend v0.2.0
Compiling wasm-bindgen-macro v0.2.0
Compiling wasm-bindgen v0.2.0
Compiling rust-c-js v0.1.0 (file:///Users/mroberts/src/personal/rust-c-js)
Finished dev [unoptimized + debuginfo] target(s) in 30.1 secs
gcc src/main.c -L target/debug -lrust_c_js -o main
LD_LIBRARY_PATH=target/debug ./main
Hello, World!
cargo build --target wasm32-unknown-unknown
Compiling libc v0.2.40
Compiling cfg-if v0.1.2
Compiling wasm-bindgen v0.2.0
Compiling rust-c-js v0.1.0 (file:///Users/mroberts/src/personal/rust-c-js)
Finished dev [unoptimized + debuginfo] target(s) in 0.94 secs
wasm-bindgen target/wasm32-unknown-unknown/debug/rust_c_js.wasm --nodejs --out-dir .
node src/main.js
/Users/mroberts/src/personal/rust-c-js/rust_c_js.js:40
cachedGlobalArgumentPtr = wasm.__wbindgen_global_argument_ptr();
^
TypeError: wasm.__wbindgen_global_argument_ptr is not a function
at globalArgumentPtr (/Users/mroberts/src/personal/rust-c-js/rust_c_js.js:40:52)
at getGlobalArgument (/Users/mroberts/src/personal/rust-c-js/rust_c_js.js:45:29)
at module.exports.__wbg_f_log_log_n (/Users/mroberts/src/personal/rust-c-js/rust_c_js.js:52:44)
at _ZN9rust_c_js3log17h1f115e1b4ecdf46cE (wasm-function[19]:116)
at _ZN9rust_c_js8do_greet17he15c7e5d2547b85bE (wasm-function[18]:285)
at _ZN9rust_c_js5greet17h7ed355f005238f2eE (wasm-function[20]:54)
at greet (wasm-function[21]:178)
at Object.<anonymous> (/Users/mroberts/src/personal/rust-c-js/src/main.js:2:1)
at Module._compile (module.js:649:30)
at Object.Module._extensions..js (module.js:660:10)
make: *** [test-js] Error 1
Next, I tried to consolidate my cfg
statements using cfg_if
. That failed with
error[E0428]: the name `__wasm_bindgen_generated_greet` is defined multiple times
src/lib.rs
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
#[macro_use]
extern crate cfg_if;
cfg_if! {
if #[cfg(target_arch = "wasm32")] {
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
#[wasm_bindgen]
pub fn greet(name: &str) {
do_greet(name);
}
} else {
extern crate libc;
use std::ffi::CStr;
use libc::c_char;
fn log(str: &str) {
println!("{}", str);
}
#[no_mangle]
pub extern "C" fn greet(name: *const c_char) {
let c_name = unsafe { CStr::from_ptr(name) };
do_greet(c_name.to_str().unwrap());
}
}
}
fn do_greet(name: &str) {
log(&format!("Hello, {}!", name));
}
$ make
cargo build
Compiling unicode-xid v0.1.0
Compiling wasm-bindgen-shared v0.2.0
Compiling fnv v1.0.6
Compiling serde v1.0.37
Compiling dtoa v0.4.2
Compiling itoa v0.4.1
Compiling num-traits v0.2.2
Compiling libc v0.2.40
Compiling cfg-if v0.1.2
Compiling proc-macro2 v0.3.6
Compiling quote v0.5.1
Compiling syn v0.13.1
Compiling serde_json v1.0.13
Compiling serde_derive_internals v0.23.0
Compiling serde_derive v1.0.37
Compiling wasm-bindgen-backend v0.2.0
Compiling wasm-bindgen-macro v0.2.0
Compiling wasm-bindgen v0.2.0
Compiling rust-c-js v0.1.0 (file:///Users/mroberts/src/personal/rust-c-js)
Finished dev [unoptimized + debuginfo] target(s) in 27.70 secs
gcc src/main.c -L target/debug -lrust_c_js -o main
LD_LIBRARY_PATH=target/debug ./main
Hello, World!
cargo build --target wasm32-unknown-unknown
Compiling libc v0.2.40
Compiling cfg-if v0.1.2
Compiling wasm-bindgen v0.2.0
Compiling rust-c-js v0.1.0 (file:///Users/mroberts/src/personal/rust-c-js)
error[E0428]: the name `__wasm_bindgen_generated_greet` is defined multiple times
--> src/lib.rs:6:1
|
6 | / cfg_if! {
7 | | if #[cfg(target_arch = "wasm32")] {
8 | |
9 | | extern crate wasm_bindgen;
... |
18 | | #[wasm_bindgen]
| | --------------- previous definition of the value `__wasm_bindgen_generated_greet` here
... |
36 | | }
37 | | }
| |_^ `__wasm_bindgen_generated_greet` redefined here
|
= note: `__wasm_bindgen_generated_greet` must be defined only once in the value namespace of this module
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error[E0428]: the name `__wasm_bindgen_generated_greet` is defined multiple times
--> <macro expansion>:1:1
|
1 | #[wasm_bindgen]
| ^ `__wasm_bindgen_generated_greet` redefined here
|
::: src/lib.rs:18:9
|
18 | #[wasm_bindgen]
| --------------- previous definition of the value `__wasm_bindgen_generated_greet` here
|
= note: `__wasm_bindgen_generated_greet` must be defined only once in the value namespace of this module
error[E0428]: the name `__wasm_bindgen_generated_greet` is defined multiple times
--> <macro expansion>:1:1
|
1 | #[wasm_bindgen]
| ^ `__wasm_bindgen_generated_greet` redefined here
|
::: src/lib.rs:18:9
|
18 | #[wasm_bindgen]
| --------------- previous definition of the value `__wasm_bindgen_generated_greet` here
|
= note: `__wasm_bindgen_generated_greet` must be defined only once in the value namespace of this module
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0428`.
error: Could not compile `rust-c-js`.
To learn more, run the command again with --verbose.
make: *** [target/wasm32-unknown-unknown/debug/rust_c_js.wasm] Error 101
Metadata
Metadata
Assignees
Labels
No labels