You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将C++库链接到WASI环境下Rust代码时遇_ZdlPv未定义错误

问题分析

env::_ZdlPv是C中operator delete(void*)的符号混淆(mangled)名称,这个错误说明你的WASM模块缺少C标准库的实现。你在build.rs中使用了.cpp_link_stdlib(None),完全禁用了C标准库的链接,但代码中使用的std::string和OpenXLSX::XLXmlData类型,其构造、析构过程会调用内存分配/释放函数(new/delete),而这些函数属于C标准库,因此出现了未定义的导入符号。

解决方案

1. 恢复C++标准库链接

移除build.rs中所有.cpp_link_stdlib(None)的调用,让cc crate自动链接WASI兼容的C标准库。如果自动链接不生效,可以手动指定链接libc:

.cpp_link_stdlib("c++")

同时,WASI环境对C++异常支持有限,建议添加编译标志禁用异常和RTTI(OpenXLSX通常不需要这些特性):

.flag("-fno-exceptions")
.flag("-fno-rtti")

2. 修改后的build.rs示例

use std::env;

fn main() {
    cc::Build::new()
        .cpp(true)
        .flag("-std=c++17")
        .flag("-stdlib=libc++")
        .flag("-fno-exceptions")
        .flag("-fno-rtti")
        .archiver("llvm-ar")
        .include("OpenXLSX/external/pugixml")
        .include("OpenXLSX/external/nowide")
        .include("OpenXLSX/external/zippy")
        .include("OpenXLSX/headers")
        .include("OpenXLSX")
        .flag("--sysroot=/opt/wasi-sysroot")
        .flag("-fvisibility=default")
        .file("OpenXLSX/sources/XLCell.cpp")
        .file("OpenXLSX/sources/XLCellIterator.cpp")
        .file("OpenXLSX/sources/XLCellRange.cpp")
        .file("OpenXLSX/sources/XLCellReference.cpp")
        .file("OpenXLSX/sources/XLCellValue.cpp")
        .file("OpenXLSX/sources/XLColor.cpp")
        .file("OpenXLSX/sources/XLColumn.cpp")
        .file("OpenXLSX/sources/XLContentTypes.cpp")
        .file("OpenXLSX/sources/XLDateTime.cpp")
        .file("OpenXLSX/sources/XLDocument.cpp")
        .file("OpenXLSX/sources/XLFormula.cpp")
        .file("OpenXLSX/sources/XLProperties.cpp")
        .file("OpenXLSX/sources/XLRelationships.cpp")
        .file("OpenXLSX/sources/XLRow.cpp")
        .file("OpenXLSX/sources/XLRowData.cpp")
        .file("OpenXLSX/sources/XLSharedStrings.cpp")
        .file("OpenXLSX/sources/XLSheet.cpp")
        .file("OpenXLSX/sources/XLWorkbook.cpp")
        .file("OpenXLSX/sources/XLXmlData.cpp")
        .file("OpenXLSX/sources/XLXmlFile.cpp")
        .file("OpenXLSX/sources/XLZipArchive.cpp")
        .file("OpenXLSX/external/pugixml/pugixml.cpp")
        .compile("OpenXLSX");

    cc::Build::new()
        .archiver("llvm-ar")
        .cpp(true)
        .flag("-stdlib=libc++")
        .flag("-fno-exceptions")
        .flag("-fno-rtti")
        .flag("-fvisibility=default")
        .flag("-std=c++17")
        .include("OpenXLSX/external/pugixml")
        .include("OpenXLSX/headers")
        .include("OpenXLSX")
        .flag("--sysroot=/opt/wasi-sysroot")
        .file("mylib.cpp")
        .compile("libmylib.a");
}

3. CMake方案补充

如果使用CMake生成OpenXLSX的WASM静态库,需要在CMakeLists.txt中指定正确的WASI目标,并启用C++标准库链接:

set(CMAKE_SYSTEM_NAME WASI)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -fno-exceptions -fno-rtti")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")

生成静态库后,在Rust的build.rs中除了链接OpenXLSX,还要确保链接C++标准库:

println!("cargo:rustc-link-lib=static=c++");
println!("cargo:rustc-link-lib=static=OpenXLSX");
println!("cargo:rustc-link-search=native={}/wasm-libs", src_dir);

4. Bindgen重复定义问题处理

Bindgen出现重复定义通常是因为OpenXLSX的头文件中存在全局符号或重复声明。可以通过以下方式缓解:

  • 使用--hide-type或--hide-function排除不需要的符号
  • 在Bindgen配置中设置blocklist_item过滤重复定义的符号
  • 确保OpenXLSX的头文件使用#pragma once或include guard避免重复包含

内容的提问来源于stack exchange,提问作者Kival M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 01:55:20