我创建了一个新的空Rust库.我将crate-type设置为cdylib,以便生成.wasm个文件.这是我的lib.rs:

#[no_mangle]
pub extern fn fibonacci(n: usize) -> usize {
  if n < 2 {
     return n;
  }

  return fibonacci(n - 1) + fibonacci(n - 2);
}

如果我删除#[no_mangle],那么Cargo会生成一个WASM二进制文件,它甚至不包含任何代码:

$ wasm-objdump -h -x target/wasm32-unknown-unknown/release/fibonacci.wasm

fibonacci.wasm: file format wasm 0x1

Sections:

    Table start=0x0000000a end=0x0000000f (size=0x00000005) count: 1
   Memory start=0x00000011 end=0x00000014 (size=0x00000003) count: 1
   Global start=0x00000016 end=0x0000002f (size=0x00000019) count: 3
   Export start=0x00000031 end=0x00000056 (size=0x00000025) count: 3
   Custom start=0x00000059 end=0x00000f5a (size=0x00000f01) ".debug_abbrev"
   Custom start=0x00000f5e end=0x0005c6df (size=0x0005b781) ".debug_info"
   Custom start=0x0005c6e3 end=0x00084461 (size=0x00027d7e) ".debug_ranges"
   Custom start=0x00084465 end=0x00118f6a (size=0x00094b05) ".debug_str"
   Custom start=0x00118f6e end=0x00152a48 (size=0x00039ada) ".debug_line"
   Custom start=0x00152a4a end=0x00152a63 (size=0x00000019) "name"
   Custom start=0x00152a65 end=0x00152ab2 (size=0x0000004d) "producers"
   Custom start=0x00152ab4 end=0x00152ae0 (size=0x0000002c) "target_features"

Section Details:

Table[1]:
 - table[0] type=funcref initial=1 max=1
Memory[1]:
 - memory[0] pages: initial=16
Global[3]:
 - global[0] i32 mutable=1 <__stack_pointer> - init i32=1048576
 - global[1] i32 mutable=0 <__data_end> - init i32=1048576
 - global[2] i32 mutable=0 <__heap_base> - init i32=1048576
Export[3]:
 - memory[0] -> "memory"
 - global[1] -> "__data_end"
 - global[2] -> "__heap_base"
Custom:
 - name: ".debug_abbrev"
Custom:
 - name: ".debug_info"
Custom:
 - name: ".debug_ranges"
Custom:
 - name: ".debug_str"
Custom:
 - name: ".debug_line"
Custom:
 - name: "name"
 - global[0] <__stack_pointer>
Custom:
 - name: "producers"
Custom:
 - name: "target_features"
  - [+] mutable-globals
  - [+] sign-ext

有没有什么方法可以在不使用#[no_mangle]的情况下强制将函数包含在二进制文件中?使用extern本身是行不通的.

推荐答案

The reference says about no_mangle that it obviously disables name mangling, but moreover it is similar to the used attribute.
However, used only applies to static items, not functions, as visible in the example below.

然后,导出函数的唯一方法就是禁用名称修改(在我看来这是合理的).

fn this_is_invisible(n: i32) -> i32 {
    n * 2 + 1
}

pub fn this_is_also_invisible(n: i32) -> i32 {
    n * 2 + 1
}

#[no_mangle]
fn this_is_accepted(n: i32) -> i32 {
    n * 2 + 1
}

/*
// ERROR: attribute must be applied to a `static` variable
#[used]
fn this_is_rejected(n: i32) -> i32 {
    n * 2 + 1
}
*/
$ nm target/debug/libmy_project.so | grep this_is
0000000000006e00 T this_is_accepted

Rust相关问答推荐

即使参数和结果具有相同类型,fn的TypId也会不同

Rust,polars CSV:有没有一种方法可以从impll BufRead(或任何字节迭代器)中读取CSV?

MutexGuard中的过滤载体不需要克隆

避免在Collect()上进行涡鱼类型的涂抹,以产生<;Vec<;_>;,_>;

在生存期内将非静态可变引用转换为范围内的静态可变引用

将serde_json读入`VEC<;T&>;`( rust 色)时出现问题

Rust函数的返回值不能引用局部变量或临时变量

rust中的库插件管理器,现在是否可行?

期望一个具有固定大小 x 元素的数组,找到一个具有 y 元素的数组

在 Rust 中,是否可以定义一个需要实现类型的构造函数的对象安全特征?

为什么我的trait 对象类型不匹配?

Rust Serde 为 Option:: 创建反序列化器

当 T 不是副本时,为什么取消引用 Box 不会抱怨移出共享引用?

使用方法、关联函数和自由函数在 Rust 中初始化函数指针之间的区别

使用 HashMap 条目时如何避免字符串键的短暂克隆?

如何在 Rust 中返回通用 struct

如何获取包裹在 Arc<> 和 RwLock<> 中的 Rust HashMap<> 的长度?

Rust 跨同一文件夹中文件的可见性

在 Traits 函数中设置生命周期的问题

在 Rust 中有条件地导入?