我有这个简单的Rust函数:
#[no_mangle]
pub fn compute(operator: &str, n1: i32, n2: i32) -> i32 {
match operator {
"SUM" => n1 + n2,
"DIFF" => n1 - n2,
"MULT" => n1 * n2,
"DIV" => n1 / n2,
_ => 0
}
}
Run Code Online (Sandbox Code Playgroud)
我正在成功地将其编译为WebAssembly,但是没有设法将operator参数从JS 传递给Rust.
调用Rust函数的JS行如下所示:
instance.exports.compute(operator, n1, n2);
Run Code Online (Sandbox Code Playgroud)
operator是JS String和n1,n2是JS Number秒.
n1并且n2正确传递并且可以在编译函数内部读取,所以我猜问题是我如何传递字符串.我想它是作为从JS到WebAssembly的指针传递,但无法找到有关其工作原理的证据或材料.
我没有使用Emscripten并希望将其保持独立(编译目标wasm32-unknown-unknown),但我看到它们将其编译的函数包装起来Module.cwrap,也许这可能会有所帮助?
有谁知道当前是否可以从编译成wasm的C#中调用C ++(或者更精确地说是Uno Platform应用程序)?
我对WebAssembly相当陌生,但是我设法将C ++函数编译为wasm并从JavaScript调用它。我还从Uno获得了一个快速入门项目(该项目可让您将用C#/ XAML编写的UWP应用编译为wasm并在浏览器中运行)。
我每天都用C#和C ++编写程序,但是我不知道是“两种语言之间的互操作” + WebAssembly组合。我假设我需要将两种语言的代码编译为2个单独的wasm文件,然后以某种方式将它们链接在一起或在运行时加载C ++。今天我什至想做些什么吗?
编辑:要明确:的想法是所有代码最终都将编译为wasm。
我提供一个静态文件服务器(通过 HTTP),其中包含由wasm-pack. 使用 rustwasm 书中的示例,我将此代码添加到我的索引 HTML 页面:
<script type="module">
import init from "./pkg/fstree_web.js";
async function run() {
await init();
}
run();
</script>
Run Code Online (Sandbox Code Playgroud)
但是,在 Firefox 上,我收到标题中所示的错误消息:
来自“ http://localhost:8000/pkg/fstree_web_bg.wasm ”的模块由于不允许的 MIME 类型(“application/wasm”)而被阻止。
我怀疑是 HTTPS 问题或 localhost 问题,所以我另外尝试了127.0.0.1,甚至尝试了 https://***.ngrok.io 隧道,但 Firefox 仍然拒绝加载带有此错误消息的 wasm 模块。
它链接到关于 X-Content-Type-Options 的 MDN 文章,但我不确定它是如何相关的。我的服务器已经在发送Content-Type: application/wasm.
wasm-pack 生成的 JavaScript 代码是这样开头的:
import { __cargo_web_snippet_72fc447820458c720c68d0d8e078ede631edd723 } from './snippets/stdweb-bb142200b065bd55/inline133.js';
import { __cargo_web_snippet_97495987af1720d8a9a923fa4683a7b683e3acd6 } from './snippets/stdweb-bb142200b065bd55/inline134.js';
import { __cargo_web_snippet_dc2fd915bd92f9e9c6a3bd15174f1414eee3dbaf } from './snippets/stdweb-bb142200b065bd55/inline135.js';
import { __cargo_web_snippet_1c30acb32a1994a07c75e804ae9855b43f191d63 } from …Run Code Online (Sandbox Code Playgroud) javascript rust webassembly wasm-pack x-content-type-options
如果您回答我关于 WebAssembly 多线程的问题,我将不胜感激。我想用 2 个线程(主线程和辅助线程)实现代码,这样就有一个全局变量用作辅助线程中的计数器变量,并在循环中递增它。和主线程,读取计数器变量,一次在运行指令之前,一次在运行指令之后(测量完成该指令所需的时间)。我已经实现了这个代码:
#include "pthread.h"
#include <stdio.h>
#include <unistd.h>
#include<chrono>
int i;
int counter;
void* timerfunction( void *ptr)
{
printf ("Thread Timer!\n");
//cout<<"Thread Timer!"<<endl;
while(1)
{
counter=counter+1;
}
pthread_exit("The thread was exited!");
}
int main()
{
pthread_t thread_id;
void *thread_result;
int c=0;
int l=pthread_create(&thread_id,NULL,timerfunction,&c);
int t1= counter;//reading the counter for the first one
//intended instruction that we want to measure its execution time
int t2= counter;//reading the counter for the second one
int t3 = t2 - t1;//computing …Run Code Online (Sandbox Code Playgroud) 我读过很多关于在 node.js 中运行 wasm 文件的文章。每当我测试代码时,它都会抛出此错误
[TypeError: WebAssembly.instantiate(): Import #0 module="wasi_snapshot_preview1" 错误:模块不是对象或函数]
然后它不会在结果中显示任何内容。我正在使用此代码:
const sp = {
env: {
memoryBase: 0,
tableBase: 0,
memory: new WebAssembly.Memory({
initial: 256
}),
table: new WebAssembly.Table({
initial: 0,
element: 'anyfunc'
})
},
imports: {
imported_func: arg => {
console.log(arg);
}
}
}
const fs = require('fs')
, wasm = WebAssembly.instantiate(new Uint8Array(fs.readFileSync('./test.wasm')), sp)
.then(result => console.log(result));
Run Code Online (Sandbox Code Playgroud)
此代码抛出上述错误。
有什么我做错了吗?
解决方案:
我的代码没有任何问题,而是我编译代码的方式有问题。而不是使用
em++ test.cpp -o test.wasm
Run Code Online (Sandbox Code Playgroud)
我应该用过:
em++ -O1 test.cpp -o test.wasm -s WASM=1
Run Code Online (Sandbox Code Playgroud) 我试图在 node.js 中本地实例化一个 .wasm 文件。目标是在本地运行二进制文件并重现网页的功能。这是我的最小可重现示例:
const fetch = require("node-fetch");
const importObject = {
imports: {
imported_func: function(arg) {
console.log(arg);
}
}
};
fetch('https://www.supremenewyork.com/ticket.wasm').then(response =>
response.arrayBuffer()
).then(bytes => {
let mod = new WebAssembly.Module(bytes);
let instance = new WebAssembly.Instance(mod, importObject);
instance.exports.exported_func();
})
Run Code Online (Sandbox Code Playgroud)
我得到的错误是: TypeError: WebAssembly.Instance(): Import #0 module="wasi_unstable" error: module is not an object or function
我看到了一些类似问题的问题,但没有提供真正的解决方案。这是我第一次与 wasm 合作,所以我很迷茫。
谢谢你的帮助。
该ctor板条箱目前不支持 Web 程序集,尽管有关于如何解决此问题的积极讨论。
尽管我很清楚与来自 C++ 的静态初始化相关的问题,但能够在启动时向工厂注册事物是一项非常方便的功能,并且在很多情况下是避免违反 DRY 原则所必需的。如果没有它,每次您想为工厂添加新的可能性时,您都必须向 中添加单独的代码main()行,如果您需要导入新函数,则可能会添加更多行。这很快就会变得乏味。
我想知道是否有可能使用过程属性宏和build.rs. 该宏将用于标记我想要注册的函数,它的实现会将"crate::your::registered_function"这些函数的模块路径 ( )保存到文件中某处的一侧,否则只是一个传递。然后build.rs将生成一个调用文件中列出的所有函数的函数,我将main()手动调用该函数。
module_path!,但如果从程序宏的定义中调用它会给模块路径为宏,而不是与什么的TokenStream将会扩展到相关的模块路径。宏可以生成对 的调用,module_path!但要等到最终程序运行时才会进行评估。我试图允许用户在 C 中调用“main”并让“main”等待 requestAnimationFrame 继续执行。即 main 可以有一个 while(1) 循环,而在 main 中,会有一个“waitForAnimationFrame”...或者允许实现像 sleep(...) 这样的函数。
我一直在挖掘 emscripten 如何实际执行此操作的内部工作原理,但它看起来不太适合我的目的。这个页面涉及了许多与我想做的事情非常接近的事情,但是当以这种方式实现时,它们似乎都没有实际工作。https://kripken.github.io/blog/wasm/2019/07/16/asyncify.html
更具体地说,似乎最好的方法是保存堆栈,然后通过 Wasm 中的虚拟函数“返回”,然后当事件在 javascript 中发生时,我可以调用一个虚拟函数但返回到正确的位置。但是,这将需要调用堆栈,它似乎不是实际的一部分STACKTOP,或者通过stackSave和可用stackRestore。最值得注意的是,无论我似乎做什么似乎都setThrew不起作用。即它只是立即返回。
我还尝试使用一些启动/停止展开功能,但由于从 Javascript 返回到 Wasm 时出现错误,因此无法在那里取得进展。
这里有什么想法吗?我真的不能像某些人想要的那样使 main 异步并期望它仍然以相同的方式工作。
编辑:好的,这是我正在测试的一些示例。
示例 1:保存/恢复堆栈
在 C 中有这两个函数:
void waittask()
{
volatile int sentinel = 85755555;
consolelog("waittask1");
waitout();
consolelog("waittask2");
}
void waitret()
{
volatile int sentinel = 12994423;
consolelog("waitret1");
stacksetup(sentinel);
stacksetup(sentinel);
consolelog("waitret2");
}
Run Code Online (Sandbox Code Playgroud)
使用 JavaScript 函数:
stacksetup : function() {
console.log( "STACK SETUP" ); …Run Code Online (Sandbox Code Playgroud) I have a blazor component with an EventCallBack parameter that utilized the new struct format allowing multiple arguments
[Parameter] public EventCallback<(EmployeeShiftDay, DateTime, DateTime)> NewDayScrolledIntoView { get; set; }
Run Code Online (Sandbox Code Playgroud)
eventcallback is invoked in child normally as such
await NewDayScrolledIntoView.InvokeAsync(p1, p2, p3);
Run Code Online (Sandbox Code Playgroud)
In my host page I have the corresponding method to handle the invoke
private void NewDayInView(EmployeeShiftDay dayInView, DateTime weekStart, DateTime weekEnd)
{
...
}
Run Code Online (Sandbox Code Playgroud)
How do I add the markup for this EventCallBack in the host component - I need …
很长一段时间以来一直在用 Go 编程,最近开始研究 WebAssembly。虽然大多数事情都很简单,但在将一些 Go 特定的结构(如通道和 goroutines)转换为 wasm 时有一个问题。在 JS 中使用时,它们的行为是否与在 Go 中使用时的行为方式相同(例如,goroutines 作为异步函数公开给 JS 等)?
webassembly ×10
javascript ×4
rust ×3
emscripten ×2
node.js ×2
.net-5 ×1
blazor ×1
c ×1
c# ×1
c++ ×1
go ×1
llvm ×1
rust-macros ×1
string ×1
uno-platform ×1
wasm-bindgen ×1
wasm-pack ×1