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

Android平台下如何向Rust编译的cdylib暴露C函数?

解决Android端Rust cdylib调用本地C函数的UnsatisfiedLinkError问题

出现java.lang.UnsatisfiedLinkError找不到符号foo的核心原因是:Rust编译的动态库(.so)加载时,依赖的符号需要在当前进程的全局符号表中可见。你当前将foo编译为静态库,若未将其链接到Rust库或提前加载的动态库中,Rust库无法找到该符号。以下是三种可行的解决方式:

方式一:将C++实现编译为动态库并提前加载

  • 修改Android模块的CMake配置,把静态库改为动态库:
    # 原配置
    # add_library(foo STATIC foo.cpp)
    # 修改后
    add_library(foo SHARED foo.cpp)
    
  • 确保foo函数暴露C接口(避免C++名字修饰),头文件需添加:
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void foo();
    
    #ifdef __cplusplus
    }
    #endif
    
  • 在Java代码中先加载foo的动态库,再加载Rust库:
    // 加载顺序不能颠倒
    System.loadLibrary("foo");
    System.loadLibrary("rust_lib"); // 替换为你的Rust库名称
    

方式二:将静态库直接链接到Rust cdylib

  • 在Rust项目的build.rs中,指定链接静态库的路径和名称:
    fn main() {
        // 替换为你的静态库所在目录路径,需匹配对应ABI(如arm64-v8a)
        println!("cargo:rustc-link-search=native=/path/to/android/static/lib");
        println!("cargo:rustc-link-lib=static=foo");
    }
    
  • 同样要保证foo是C接口(extern "C"声明),且静态库与Rust库的编译ABI完全一致(如均为arm64-v8a)。

方式三:将C++代码纳入Rust构建流程

  • 把实现foo的C++文件放到Rust项目中,通过build.rs调用编译器生成静态库并链接:
    use std::process::Command;
    use std::env;
    
    fn main() {
        let target = env::var("TARGET").unwrap();
        let out_dir = env::var("OUT_DIR").unwrap();
        
        // 编译C++文件为目标文件
        Command::new("clang++")
            .args(&[
                "-c", 
                "src/foo.cpp", 
                "-o", &format!("{}/foo.o", out_dir),
                "--target", &target,
                "-fPIC"
            ])
            .status().unwrap();
        
        // 打包为静态库
        Command::new("ar")
            .args(&["rcs", &format!("{}/libfoo.a", out_dir), &format!("{}/foo.o", out_dir)])
            .status().unwrap();
        
        // 告知Rust链接该静态库
        println!("cargo:rustc-link-lib=static=foo");
        println!("cargo:rustc-link-search=native={}", out_dir);
    }
    
  • Rust代码中通过extern "C"声明调用foo:
    extern "C" {
        fn foo();
    }
    
    // 调用示例
    pub fn call_foo() {
        unsafe { foo(); }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:57:20