You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust外部模块导入问题:如何完成tests9.rs测试任务?

解决Rust tests9.rs练习问题:导出函数并设置别名

核心要求

让测试代码能调用Foo模块中的my_demo_function,同时让my_demo_function_alias成为该函数的别名,仅添加两行属性,不能修改现有代码逻辑。

解决方案

需要添加的两行属性分别作用于两个位置:

  1. 给Foo模块内的my_demo_function添加#[no_mangle],禁用Rust默认的符号混淆,让外部能通过函数名找到它;
  2. 给extern块内的my_demo_function_alias添加#[link_name = "my_demo_function"],指定它链接到my_demo_function的符号,作为别名。

修改后的完整代码

// tests9.rs
// 
// Rust is highly capable of sharing FFI interfaces with C/C++ and other statically compiled
// languages, and it can even link within the code itself! It makes it through the extern block, just like the code below.
// 
// The short string after the `extern`keyword indicates which ABI the externally imported 
// function would follow. In this exercise, "Rust" is used, while other variants exists like 
// "C" for standard C ABI, "stdcall" for the Windows ABI. 
// 
// The externally imported functions are declared in the extern blocks, with a semicolon to 
// mark the end of signature instead of curly braces. Some attributes can be applied to those 
// function declarations to modify the linking behavior, such as #[link_name = ".."] to modify the actual symbol names. 
// 
// If you want to export your symbol to the linking environment, the`extern`keyword can 
// also be marked before a function definition with the same ABI string note. The default ABI 
// for Rust functions is literally "Rust", so if you want to link against pure Rust functions, 
// the whole extern term can be omitted. 
// 
// Rust mangles symbols by default, just like C++ does. To suppress this behavior and make 
// those functions addressable by name, the attribute #[no_mangle] can be applied. 
// 
// In this exercise, your task is to make the testcase able to call the`my_demo_function`in 
// module Foo. the`my_demo_function_alias`is an alias for`my_demo_function`, so the two
// line of code in the testcase should call the same function.
//
// You should NOT modify any existing code except for adding two lines of attributes.

// I AM NOT DONE

extern "Rust" {
    fn my_demo_function(a: u32) -> u32;
    // 新增:给别名指定链接的符号名
    #[link_name = "my_demo_function"]
    fn my_demo_function_alias(a: u32) -> u32;
}

mod Foo {
    // No `extern` equals `extern "Rust"`.
    // 新增:禁用符号混淆,让外部能找到这个函数
    #[no_mangle]
    fn my_demo_function(a: u32) -> u32 {
        a
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_success() {
        // The externally imported functions are UNSAFE by default
        // because of untrusted source of other languages. You may
        // wrap them in safe Rust APIs to ease the burden of callers.
        //
        // SAFETY: We know those functions are aliases of a safe
        // Rust function.
        unsafe {
            my_demo_function(123);
            my_demo_function_alias(456);
        }
    }
}

原理说明

  • #[no_mangle]:Rust默认会对函数名进行符号混淆(类似C++),添加这个属性后,函数会以原始名称my_demo_function暴露给链接器,让外部的extern声明能找到它;
  • #[link_name = "my_demo_function"]:告诉Rust,这个my_demo_function_alias的声明实际要链接到符号my_demo_function,相当于给原函数起了一个别名,因此两个外部调用最终都会指向Foo模块里的同一个函数。

内容的提问来源于stack exchange,提问作者herimone tommie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 13:58:13