如何在多个同名模块中“外部”一个函数?

And*_*zie 3 rust webassembly

我有一个 lib 项目,其中包含多个名为one和 的模块two,位于单独的文件中。每个模块都有一个名为的函数run

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

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

fn main() {
    one::run();
    two::run();
}
Run Code Online (Sandbox Code Playgroud)

操场

我想将每个文件/函数编译为 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();
}
Run Code Online (Sandbox Code Playgroud)

操场

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

She*_*ter 5

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

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

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();
}
Run Code Online (Sandbox Code Playgroud)

也可以看看:

  • @AndrewMackenzie 不,它是`no_mangle`:“不要破坏这个函数名称,这样它(很可能)在全局命名空间中是唯一的,我会处理它。” (3认同)