我正在使用
构建 WASM。构建 WASM 文件后,我用
wasm-objdump
检查它,发现没有导出的函数。我需要知道我做错了什么。该项目只是一个解决问题的玩具项目。
这是
hpp/demo.hpp
。
#ifndef API_DEMO_H
#define API_DEMO_H
int add(int a, int b);
#endif
这是
cpp/demo.cpp
。
#include "demo.hpp"
int add(int a, int b) {
return a + b;
}
这是
cpp/CMakeLists.txt
。
include_directories(../hpp)
file(GLOB_RECURSE SRC *.cpp)
add_executable(api ${SRC})
set_target_properties(api PROPERTIES COMPILE_FLAGS "--no-entry")
set_target_properties(api PROPERTIES LINK_FLAGS "--no-entry")
还有
CMakeLists.txt
。
cmake_minimum_required(VERSION 3.10)
project(api)
set(CMAKE_CXX_FLAGS_INIT "-std=c++17")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_CXX_FLAGS "-O3 -DNDEBUG")
set(CMAKE_EXECUTABLE_SUFFIX ".wasm")
add_subdirectory(cpp)
要构建项目,我输入以下内容。
emcmake cmake -B build -S .
cmake --build build -j 8
文件
build/cpp/api.wasm
已构建,没有错误。但随后我发出命令 wasm-objdump -x build/cpp/api.wasm
并观察以下内容。如您所见,add
函数未导出。有什么想法吗?
api.wasm: file format wasm 0x1
Section Details:
Type[4]:
- type[0] () -> i32
- type[1] () -> nil
- type[2] (i32) -> nil
- type[3] (i32) -> i32
Function[5]:
- func[0] sig=1 <_initialize>
- func[1] sig=0 <__errno_location>
- func[2] sig=0 <stackSave>
- func[3] sig=2 <stackRestore>
- func[4] sig=3 <stackAlloc>
Table[1]:
- table[0] type=funcref initial=2 max=2
Memory[1]:
- memory[0] pages: initial=256 max=256
Global[1]:
- global[0] i32 mutable=1 - init i32=66576
Export[7]:
- memory[0] -> "memory"
- func[0] <_initialize> -> "_initialize"
- table[0] -> "__indirect_function_table"
- func[1] <__errno_location> -> "__errno_location"
- func[2] <stackSave> -> "stackSave"
- func[3] <stackRestore> -> "stackRestore"
- func[4] <stackAlloc> -> "stackAlloc"
Elem[1]:
- segment[0] flags=0 table=0 count=1 - init i32=1
- elem[1] = func[0] <_initialize>
Code[5]:
- func[0] size=3 <_initialize>
- func[1] size=5 <__errno_location>
- func[2] size=4 <stackSave>
- func[3] size=6 <stackRestore>
- func[4] size=16 <stackAlloc>
未导出的
add
函数也在 HTML/JavaScript 端进行了验证,显示 undefined
。
<html>
<head>
<title>Simple template</title>
</head>
<body>
<script>
const importObject = {
env: {
__linear_memory: new WebAssembly.Memory({ initial: 256 }),
__stack_pointer: new WebAssembly.Global({value:'i32', mutable:true,}, 0),
}
};
WebAssembly.instantiateStreaming(
fetch('build/cpp/api.wasm'),
importObject
).then(result => {
console.log(result);
console.log(result.instance.exports);
console.log(result.instance.exports.add); // undefined
});
</script>
</body>
</html>
也许有帮助。我使用 wasi 而不是 emscripten。不要误会我的意思,emscripten 很好,但对于我的项目,我需要在 rust 中调用 c/c++ 函数,处理值并通过 wasm_bindgen 将其发送回 JS。虽然 C 函数可以正常工作,但 cpp 函数需要一些返工。
#define export __attribute__((visibility("default")))
extern "C" export int something()
{
return 0;
}
在您的情况下,
cpp/demo.cpp
文件应如下所示:
#include "demo.hpp"
#define export __attribute__((visibility("default")))
extern "C" export int add(int a, int b)
{
return a + b;
}