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

C++调用Rust后回调C++的链接报错问题(游戏模组场景)

问题根源

报错undefined reference to 'cpp'是因为Rust生成的动态库libexternal.so需要调用的C函数cpp(),在最终编译的C可执行文件中没有被导出,或者链接器无法在符号表中找到它。单独C调用Rust正常,说明单向调用的符号导出没问题,但双向调用时,C的函数符号没有对动态库开放。

解决步骤

1. 统一C++与Rust的函数符号规则

C默认会对函数名做名字修饰,导致Rust无法匹配到正确的符号。必须用extern "C"强制C生成无修饰的C风格符号:

  • 在main.h中声明:
    #ifndef MAIN_H
    #define MAIN_H
    
    extern "C" void cpp();
    
    #endif
    
  • 在main.cpp中实现:
    #include "main.h"
    #include "rust.h"
    #include <iostream>
    
    void cpp() {
        std::cout << "C++ function called from Rust" << std::endl;
    }
    
    int main() {
        rust();
        return 0;
    }
    

2. 修正Rust中的函数声明

在Rust代码中,必须用extern "C"块声明要调用的C++函数,保证符号匹配:
比如cpp.rs中:

extern "C" {
    pub fn cpp();
}

pub fn call_cpp() {
    unsafe {
        cpp();
    }
}

lib.rs中导出供C++调用的函数:

mod cpp;

#[no_mangle]
pub extern "C" fn rust() {
    cpp::call_cpp();
}

3. 调整C++编译命令,导出可执行文件符号

Linux下默认可执行文件不会导出全局符号,动态库无法引用其中的函数。必须添加-rdynamic参数让可执行文件导出符号:

g++ -L ./external/target/debug/ -Wall main.cpp -l external -rdynamic

-rdynamic会强制将可执行文件的全局符号加入动态符号表,让Rust的动态库能找到cpp()的实现。

4. 重新编译验证

  1. 先重新编译Rust动态库:cd external && cargo build
  2. 用上述命令编译C++程序
  3. 运行生成的可执行文件,即可看到Rust成功回调C++的cpp()函数。
避坑提示
  • 不要省略extern "C":C++的名字修饰会让符号名变成类似_Z3cppv的形式,Rust根本找不到这个符号。
  • 必须加-rdynamic:没有这个参数,可执行文件的符号不会对外暴露,动态库永远找不到依赖的函数。
  • 检查链接顺序:确保-l external在源文件之后,链接器会按顺序解析符号,避免符号未定义的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 05:12:48