如何"extern"多个同名模块中的一个函数?

How to "extern" a function in multiple modules with the same name?

我有一个 lib 项目,其中包含多个名为 onetwo 的模块,位于不同的文件中。每个模块都有一个名为 run:

的函数
mod one {
    pub fn run() {
        println!("One");
    }
}

mod two {
    pub fn run() {
        println!("Two");
    }
}

fn main() {
    one::run();
    two::run();
}

Playground

我想将这些 files/functions 中的每一个都编译成 WebAssembly,然后能够加载它们并调用函数 run().

我想我必须添加 #[no_mangle] 指令并将它们标记为 extern "C" 函数。当我这样做时,run 函数会发生名称冲突,尽管有模块结构。

这是无法编译的修改版本:

mod one {
    #[no_mangle]
    pub extern "C" fn run() {
        println!("One");
    }
}

mod two {
    #[no_mangle]
    pub extern "C" fn run() {
        println!("Two");
    }
}

fn main() {
    one::run();
    two::run();
}

Playground

有没有办法在一个项目中有多个模块,每个模块都有一个同名的函数,这样我就可以将带有函数的文件编译为 WebAssembly,同时保留函数名?

不,您不能在全局命名空间中为多个事物赋予相同的名称。这就是名称和名称空间的定义。您需要将它们导出为两个不同的名称。

我更喜欢有一个单一的位置来导出东西,这样更容易看到并防止冲突。此外,您的符号在 所有 将与您的库链接的库中应该是唯一的。这就是为什么大多数高质量的 C 项目在每个 public 方法中都使用库名称的原因。

mod one {
    pub fn run() {
        println!("One");
    }
}

mod two {
    pub fn run() {
        println!("Two");
    }
}

#[no_mangle]
pub extern "C" fn mylib_one_run() {
    one::run()
}

#[no_mangle]
pub extern "C" fn mylib_two_run() {
    two::run()
}

fn main() {
    one::run();
    two::run();
}

另请参阅: