我正在尝试将一个C++库编译到wasm32 wasi,以便在我的锈蚀应用程序中使用。然而,我正在讨论这个问题。
Error: failed to run main module `target/wasm32-wasi/release/so.wasm`
Caused by:
0: failed to instantiate "target/wasm32-wasi/release/so.wasm"
1: unknown import: `env::_ZdlPv` has not been defined此错误与我的mylib.cpp中的第5行有关。它刚刚声明了一个变量
#include "OpenXLSX/OpenXLSX.hpp"
extern "C" int test() {
std::string i = "";
OpenXLSX::XLXmlData s;
return 0;
}我的main.rs
#[link(name = "mylib")]
extern "C" {
pub fn test() -> i32;
}
pub fn main() {
let res = unsafe { test() };
println!("test code: {}", res);
}以及我的build.rs,其中我假设错误是
use std::env;
fn main() {
cc::Build::new()
.cpp_link_stdlib(None)
.cpp(true)
.flag("-std=c++17")
.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_link_stdlib(None)
.cpp(true)
.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");
}在另一次尝试中,在我的build.rs中,我尝试链接OpenXLSX文件,而不是步骤1,我还使用cmake生成了一个single.wassysroot编译为wasm32-wasi的文件,我尝试加载该文件。
let src_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
println!("cargo:rustc-link-lib=static=OpenXLSX");
println!("cargo:rustc-link-search=native={}/wasm-libs", src_dir);我尝试用Bindgen生成绑定,它给了我重复的定义错误。这就是我用c++函数编写代码并试图从铁锈中调用它的主要原因。我假设仍然存在链接问题,即使我让bindgen工作。
发布于 2022-09-13 23:24:40
简而言之,您的c++代码使用的是operator delete(void*),但您是而不是,它链接了通常为其提供实现的c++标准库。
更详细的是:
_ZdlPv是operator delete(void*)的拙劣名称。这是标准的C++ delete操作符,用于释放在堆上分配的带有new的对象。检查这就是答案。您还可以在Demangler.com上检查名称。OpenXLSX::XLXmlData s;上,您正在创建一个XLXmlData实例。XLXmlData有一个ptr作为成员。因此,当XLXmlData对象超出作用域时(在test()的末尾),它的析构函数~XLXmlData()被调用,编译器生成代码来清理所有成员,包括unique_ptr。此代码包含对delete运算符的调用。
检查这个(简写的) godbolt.org版本的XLXmlData,看看生成什么代码。对delete的调用位于第38行。delete是一个C++关键字,但在幕后,编译器只发出一个常规的函数调用(正如我们已经看到的那样,在损坏的_ZdlPv名称下),所以需要为该符号提供一些实现。这个“东西”通常是C++标准库。build.rs将None传递给.cpp_link_stdlib()。根据医生的说法禁止自动链接,因此链接器不会在标准库中查找delete的实现。由于没有其他实现delete,这最终导致您正在看到的unknown import错误。综上所述,您应该链接到标准库。没有它,很多C++东西就无法工作。
https://stackoverflow.com/questions/73636071
复制相似问题