Lut*_*her 5 c++ mismatch emscripten
我已经通过 emscripten 使用 WASM 几个星期了,并且取得了良好的进展,直到出现此错误:
exception thrown: RuntimeError: function signature mismatch,RuntimeError: function signature mismatch
Run Code Online (Sandbox Code Playgroud)
这种情况开始发生在以前可以工作的代码中,似乎与 WASM 缺乏对 javascript 中 64 位整数的支持以及文件管理中使用的偏移量有关。我做了一个孤立的案例:
#include <iostream>
int main(int argc, char const *argv[])
{
char test[30];
std::cout << __LINE__ << std::endl;
FILE *f = fopen("minimal_call_dispatch.cpp","ra");
std::cout << __LINE__ << std::endl;
fseek(f, 100, SEEK_SET);
std::cout << __LINE__ << std::endl;
fclose(f);
std::cout << __LINE__ << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
建筑:
call emcc -o ./test.js test_file.cpp -s WASM=1 -s NO_EXIT_RUNTIME=1 -std=c++1z
Run Code Online (Sandbox Code Playgroud)
由于上述错误,在“fseek”失败之前会输出“6\n8\n”。
在此过程中,我怀疑 wasm 正在尝试使用与具有 64 位整数而不是 32 位整数的 javascript 进行通信的标头,但我不明白这是如何发生的。我将尝试重新安装 emscripten,但即使有效,我也想更好地了解导致此问题的原因。
作为解决方法,有人知道如何让 emcc 忽略对 64 位整数的担忧并默默地将它们转换为 32 位吗?毕竟,我不想讨论超过 3G 的内存。
您收到错误只是因为您的代码错误。
i64内部支持 64 位整数,并且可以很好地计算 64 位整数。它只是没有 64 位地址。)这意味着编译器已经知道目标机器是 32 位并且size_t将会是 32 位。"ra"with会导致分段错误!fopen()r好的,让我们在本机环境中尝试一下。
g++ test_file.cpp -o test.out
Run Code Online (Sandbox Code Playgroud)
如果不存在,运行./test.out将打印以下内容:test_file.cpp
6
8
[2] 14464 segmentation fault (core dumped) ./test.out
Run Code Online (Sandbox Code Playgroud)
所以你的代码是错误的,但为什么 Emscripten 会以不同的方式抛出错误?当您在emcc不使用诸如 之类的调试标志的情况下使用-g时,它将具有最小化的环境,不会捕获诸如段错误之类的错误,因为这种智能运行时会增加二进制文件的大小,这在 Web 环境中至关重要。因此,运行时会忽略段而继续运行,最终会出现随机错误。所以function signature mismatch没有什么意义。
您可以使用与调试相关的选项来构建它:
emcc -o ./test.html test_file.cpp -s WASM=1 -std=c++1z \
-g4 -s ASSERTIONS=2 -s SAFE_HEAP=1 -s STACK_OVERFLOW_CHECK=1 \
--source-map-base http://your_server_ip:port/
Run Code Online (Sandbox Code Playgroud)
然后打开test.html你现在会看到正确的错误:
exception thrown: RuntimeError: abort(segmentation fault) at Error
Run Code Online (Sandbox Code Playgroud)
现在您将不会遇到诸如签名不匹配之类的误导性错误:)
顺便说一句,替换fopen("minimal_call_dispatch.cpp","ra");为fopen("minimal_call_dispatch.cpp","a");将修复错误。
正确--source-map-base设置服务器IP,您将获得更好的调试体验。例如,您将test_file.cpp在浏览器中获取源代码,以便可以在 .cpp 文件中设置断点。
享受调试的乐趣:)