首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++库与wasi中的锈蚀代码的链接问题

C++库与wasi中的锈蚀代码的链接问题
EN

Stack Overflow用户
提问于 2022-09-07 13:05:46
回答 1查看 189关注 0票数 1

我正在尝试将一个C++库编译到wasm32 wasi,以便在我的锈蚀应用程序中使用。然而,我正在讨论这个问题。

代码语言:javascript
复制
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行有关。它刚刚声明了一个变量

代码语言:javascript
复制
#include "OpenXLSX/OpenXLSX.hpp"

extern "C" int test() {
  std::string i = "";
  OpenXLSX::XLXmlData s;
  return 0;
}

我的main.rs

代码语言:javascript
复制
#[link(name = "mylib")]
extern "C" {
    pub fn test() -> i32;
}

pub fn main() {
    let res = unsafe { test() };
    println!("test code: {}", res);
}

以及我的build.rs,其中我假设错误是

代码语言:javascript
复制
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的文件,我尝试加载该文件。

代码语言:javascript
复制
 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工作。

EN

回答 1

Stack Overflow用户

发布于 2022-09-13 23:24:40

简而言之,您的c++代码使用的是operator delete(void*),但您是而不是,它链接了通常为其提供实现的c++标准库。

更详细的是:

  • _ZdlPvoperator delete(void*)的拙劣名称。这是标准的C++ delete操作符,用于释放在堆上分配的带有new的对象。检查这就是答案。您还可以在Demangler.com上检查名称。
  • 在第5行OpenXLSX::XLXmlData s;上,您正在创建一个XLXmlData实例。XLXmlData有一个ptr作为成员。因此,当XLXmlData对象超出作用域时(在test()的末尾),它的析构函数~XLXmlData()被调用,编译器生成代码来清理所有成员,包括unique_ptr。此代码包含对delete运算符的调用。 检查这个(简写的) godbolt.org版本的XLXmlData,看看生成什么代码。对delete的调用位于第38行。
  • 尽管delete是一个C++关键字,但在幕后,编译器只发出一个常规的函数调用(正如我们已经看到的那样,在损坏的_ZdlPv名称下),所以需要为该符号提供一些实现。这个“东西”通常是C++标准库。
  • 但是,build.rsNone传递给.cpp_link_stdlib()根据医生的说法禁止自动链接,因此链接器不会在标准库中查找delete的实现。由于没有其他实现delete,这最终导致您正在看到的unknown import错误。

综上所述,您应该链接到标准库。没有它,很多C++东西就无法工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73636071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档