使用Emscripten编译libGD项目时遇Uncaught RuntimeError系列错误的排查求助
Let's walk through the two key errors you're facing and fix them step by step:
1. First Error: Uncaught RuntimeError: indirect call to null
This error usually pops up when Emscripten's generated JS wrapper tries to call a function that isn't properly registered in the Wasm indirect function table. For libGD projects, this almost always comes from using a native libGD library instead of one cross-compiled specifically for Emscripten. Native libGD binaries contain machine code that doesn't translate to Wasm, leading to missing or invalid function pointers.
2. Second Error: Aborted(Assertion failed: exported native function main not found)
When you added , true (likely modifying a JS wrapper call), you broke the connection between your C++ main() function and Emscripten's runtime. Emscripten relies on explicitly exported functions to hook into your program's entry point, and without proper export flags, it can't locate your main function.
Fix Steps
Step 1: Cross-Compile libGD for Emscripten
You can't use a standard native libgd library with Emscripten. Build libGD from source using the Emscripten toolchain to get a Wasm-compatible version:
# First activate your Emscripten environment (run source emsdk_env.sh or equivalent) git clone https://github.com/libgd/libgd.git cd libgd mkdir build-emscripten && cd build-emscripten emcmake cmake .. -DBUILD_SHARED_LIBS=OFF -DENABLE_FREETYPE=OFF # Adjust features based on your needs emmake make -j4
This will generate a libgd.a static library that works with Wasm.
Step 2: Update Your Compilation Command
Use the cross-compiled libGD and add critical Emscripten flags to export your main function and handle runtime linking correctly:
em++ ./main.cpp -L/path/to/libgd/build-emscripten -lgd \ -s EXPORTED_FUNCTIONS=['_main'] \ -s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'cwrap'] \ -s ALLOW_MEMORY_GROWTH=1 \ -o index.html
-s EXPORTED_FUNCTIONS=['_main']: Tells Emscripten explicitly to export yourmainfunction (note the leading underscore, added by C name mangling).-s ALLOW_MEMORY_GROWTH=1: Prevents memory-related crashes common with graphics libraries like libGD.-L/path/to/libgd/build-emscripten: Points to the directory where your cross-compiled libGD library lives.
Step 3: Verify Your main Function Signature
Make sure your main.cpp has a standard entry point that won't get optimized out by the compiler:
#include <gd.h> #include <iostream> int main() { std::cout << "Wasm initialized" << std::endl; // Add your libGD logic here return 0; }
Avoid non-standard signatures (like int main(int argc, char** argv) if you aren't passing command-line arguments) that might be stripped during compilation.
Why This Works
Cross-compiling libGD ensures all its functions are compatible with Wasm and properly registered in Emscripten's function tables. The EXPORTED_FUNCTIONS flag guarantees Emscripten can locate your main function to start execution, eliminating both the indirect call and missing function errors.
内容的提问来源于stack exchange,提问作者Ryufuz

