为什么在每个导出的WASM函数中都调用对象的构造函数?

发布于 2025-02-06 07:52:02 字数 1158 浏览 1 评论 0 原文

我正在为WASM模块编译一些C ++

struct Test{
    Test(){
        printf("Constructed");
    }
};

Test t;

EXPORT void init(){...}
EXPORT void update(){...}
EXPORT void uninit(){...}

,我希望该构造函数仅用于t,但是查看Chrome的调试器表明,T的构造函数在每个导出函数的顶部都称为t的构造函数(func18是构造函数):

...
(func $init (;23;) (export "init")
    (local $var0 i32) (local $var1 i32) (local $var2 i32) (local $var3 i32) (local $var4 i32) (local $var5 i32)
    call $func18
...
(func $update (;24;) (export "update")
    (local $var1 i32)
    call $func18
...
(func $uninit (;25;) (export "uninit")
    (local $var0 i32) (local $var1 i32) (local $var2 i32)
    call $func18
...

我知道必须将构造函数称为 ,但是我如何控制它的位置并阻止每个函数调用它呢?是否可以通过clang ++的命令行参数来控制这一点?

这是我一直使用的命令:

clang++ 
-Wall 
--target=wasm32 
-Ofast 
-flto 
--no-standard-libraries 
-Wl,--export=init 
-Wl,--export=update 
-Wl,--export=uninit 
-Wl,--no-entry 
-Wl,--lto-O3 
-Wl,-allow-undefined-file=wasm.syms 
-Wl,--import-memory 
-o ./bin/main.wasm 
-I./src 
./src/lib.cpp 
./src/main.cpp

我应该注意,我不使用emscripten或任何库/框架。

I'm compiling some c++ for a WASM module

struct Test{
    Test(){
        printf("Constructed");
    }
};

Test t;

EXPORT void init(){...}
EXPORT void update(){...}
EXPORT void uninit(){...}

I would expect the constructor to only be called once for t, but looking at chrome's debugger shows that the constructor for t is called near the top of every exported function (func18 is the constructor):

...
(func $init (;23;) (export "init")
    (local $var0 i32) (local $var1 i32) (local $var2 i32) (local $var3 i32) (local $var4 i32) (local $var5 i32)
    call $func18
...
(func $update (;24;) (export "update")
    (local $var1 i32)
    call $func18
...
(func $uninit (;25;) (export "uninit")
    (local $var0 i32) (local $var1 i32) (local $var2 i32)
    call $func18
...

I know that the constructor has to be called somewhere, but how can I control where it's called and stop every function from calling it? Is it possible to control this through the command line arguments for clang++?

This is the command I've been using to compile this:

clang++ 
-Wall 
--target=wasm32 
-Ofast 
-flto 
--no-standard-libraries 
-Wl,--export=init 
-Wl,--export=update 
-Wl,--export=uninit 
-Wl,--no-entry 
-Wl,--lto-O3 
-Wl,-allow-undefined-file=wasm.syms 
-Wl,--import-memory 
-o ./bin/main.wasm 
-I./src 
./src/lib.cpp 
./src/main.cpp

I should note that I'm not using Emscripten or any libraries/frameworks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你好,陌生人 2025-02-13 07:52:02

请参阅

我认为正在发生的事情是在这种情况下,链接器决定您使用命令ABI,并且应用程序的每个输入点都是独立的命令。

您实际试图构建的是该文档中称为反应堆。

构建反应器的最简单方法是包括某种crt1.c文件,例如WASI-SDK使用的一个文件: https://github.com/webassembly/wasi-libc/blob/blob/main/libc-bottom-half/-half/crt/crt/crt1-reacector一下.c

如果导出 _Iniitialize 函数,又引用了 __ wasm_call_ctors 函数,那是一个信号,这是链接器,您要称呼您的ctors。一次,您正在构建一个反应堆。

See https://github.com/WebAssembly/WASI/blob/main/legacy/application-abi.md

I think what is happening is that the linker in this case deciding that you using the command abi, and each entry point to your application is a standalone command.

What you are actually trying to build is that is referred to in that document as a reactor.

The easiest way to build a reactor is to include some kind of crt1.c file such as the one that wasi-sdk uses: https://github.com/WebAssembly/wasi-libc/blob/main/libc-bottom-half/crt/crt1-reactor.c

If you export the _iniitialize function, which in turn references the __wasm_call_ctors function, that is a signal the linker that you the ctors are to be called just once and you are building a reactor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文