WebAssembly wasm C++ js代码调用C++方法时,如果使用std::thread,会报错

将C++代码使用wasm编译成js代码,在调用到C++内部的std::thread时报错。

C++代码片段如下:

#include <thread>
#include <iostream>

EM_PORT_API(int) testThread(int a){
    std::thread t1;
    auto lambda = [](int a) {
        std::cout << a << '\n';
    };
    std::thread thread(lambda, 10);
    return 1;
}

编译代码:emcc -std=c++11 api.cpp -o api.js

报错堆栈:

Uncaught (in promise) RuntimeError: Aborted(native code called abort())
    at abort (api.js:919:11)
    at _abort (api.js:1285:7)
    at api.wasm:0x22eff
    at api.wasm:0x1142
    at api.wasm:0xfca
    at Object._testThread (api.js:963:22)
    at Module.onRuntimeInitialized (api.html:11:26)
    at doRun (api.js:5243:71)
    at run (api.js:5260:5)
    at runCaller (api.js:5165:19)

请问有遇到相同的问题吗?应该怎么解决,谢谢 :smiley:

-s USE_PTHREADS

wasm命令更改为
emcc -std=c++11 -s USE_PTHREADS api.cpp -o api.js

然后出现了另外一个问题:

加头
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

https://developer.chrome.com/blog/enabling-shared-array-buffer/

谢谢。上面的问题已经解决了。

但是,还有一个新的问题需要请教下:

我看了下文档,是不是需要将用到的三方库,使用 -sSIDE_MODULE生成wasm文件,然后最后生成api.js时,使用下面的命令,就能够解决上面的报错。
emcc -sMAIN_MODULE api.cpp libsomething.wasm

超出我的知识范围:grin:

尝试了下,在生成.a文件的时候,添加 -SIDE_MODULE,生成js的时候,添加-sMAIN_MODULE,可以解决动态链接的问题。(好像还是有问题,有个error)

new 问题来了 :smile:

这里我们期望是走c++代码封装好的逻辑,但是却走到了js的websocket,这是为什么?

应该跑不了c++的tcp代码的,wasm也是在浏览器沙盒里的,和js一样只能http,websocket。猜测emscripten搞了什么戏法帮你转成了websocket

因为现在前后端都是使用的tcp。如果客户端使用js的http、websocket,是不是意味着后端的逻辑也得进行websocket的支持?

是的~~~~~~~~~~~~

Uncaught RuntimeError: Aborted(Assertion failed: exceptfds not supported)
    at abort (api.js:1040:11)
    at assert (api.js:509:5)
    at ___syscall__newselect (api.js:5195:7)
    at _emscripten_receive_on_main_thread_js (api.js:15730:19)
    at api.wasm:0x2b197d
    at api.wasm:0x2b8e6a
    at api.js:1084:22
    at executeNotifiedProxyingQueue (api.js:7922:9)
    at worker.onmessage (api.js:3823:13)

请问,这个问题应该怎么解决下?

WebAssembly不要想用裸socket

网络通信用websocket 实现一下 让服务器支持一下 工作量很小

pthread 也尽量别用。浏览器兼容性很差

自己写一个中间组件 我们的服务器也是只支持TCP 然后我用GO 写了一个带来 把客户端的websocket 转成 TCP 之后在发给服务器