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

如何在Rust控制台程序调用FFI函数并通过Linux终端测试?

问题描述

我有一个暴露了若干FFI函数的Rust库,已知该库可在C#中正常调用。现在需要解决两个问题:

  1. 如何在Rust控制台程序中正确调用这些FFI函数
  2. 能否通过Linux终端直接测试该库的FFI函数

库实现代码

const CUR_VERSION: &str = "0.1";

#[no_mangle]
pub extern "C" fn get_version() -> *const c_char {
    let c_string = CString::new(CUR_VERSION).expect("CString::new failed");
    c_string.into_raw()
}

尝试的调用代码(未成功)

extern crate core;
use std::ffi::c_char;

#[cfg_attr(unix, link(name = "my_dll.so", kind = "dylib"))]
extern "C" {
    fn get_version() -> *const c_char;
}

fn main() {
    unsafe {
        println!("Result: {:?}", get_version());
    }
}

报错信息

编译时触发链接错误:error: linking with 'cc' failed: exit status: 1,核心错误为cannot find -lmy_dll.so,即编译器找不到指定的动态库。


解决方案

一、修复Rust控制台程序的调用问题

你的代码核心问题是链接库的配置错误,按以下步骤修正:

  1. 修正链接属性写法
    link(name = "my_dll.so") 写法错误,name 参数仅需填写库的名称(去掉.so后缀),正确配置:
#[cfg_attr(unix, link(name = "my_dll", kind = "dylib"))]
// Windows环境下若为dll文件,对应写法:#[cfg_attr(windows, link(name = "my_dll", kind = "dylib"))]
  1. 确保库文件路径可被编译器找到
  • Linux下,动态库文件(libmy_dll.so)需放在系统默认库路径(如/usr/lib),或编译前通过环境变量指定路径:
    export LD_LIBRARY_PATH=/path/to/your/library:$LD_LIBRARY_PATH
    
  • 也可在编译时直接传递链接参数:
    rustc your_program.rs -L /path/to/your/library
    
  1. 正确处理返回的C字符串
    原代码仅打印指针地址,需将指针转换为Rust字符串输出,同时注意回收into_raw()创建的指针避免内存泄漏:
extern crate core;
use std::ffi::{c_char, CString};

#[cfg_attr(unix, link(name = "my_dll", kind = "dylib"))]
extern "C" {
    fn get_version() -> *const c_char;
}

fn main() {
    unsafe {
        let version_ptr = get_version();
        let version_str = CString::from_raw(version_ptr as *mut c_char);
        println!("Version: {}", version_str.into_string().unwrap());
    }
}

二、Linux终端测试FFI库的方法

可以通过以下三种方式直接在终端验证库的可用性:

方法1:用nm命令确认导出函数

检查库是否正确导出get_version函数:

nm -D libmy_dll.so | grep get_version

若输出类似0000000000001120 T get_version,说明函数已成功导出。

方法2:用Python的cffi快速验证

  1. 安装依赖:
    pip install cffi
    
  2. 创建测试脚本test_lib.py:
    from cffi import FFI
    
    ffi = FFI()
    ffi.cdef("const char* get_version();")
    lib = ffi.dlopen("/path/to/libmy_dll.so")
    
    version = ffi.string(lib.get_version()).decode('utf-8')
    print(f"Version: {version}")
    
  3. 运行脚本:
    python test_lib.py
    

方法3:用C语言编写测试程序

  1. 创建test.c:
    #include <stdio.h>
    
    extern const char* get_version();
    
    int main() {
        const char* version = get_version();
        printf("Version: %s\n", version);
        // 注意:Rust库用into_raw()返回的指针,此处无需free,否则会触发double free
        return 0;
    }
    
  2. 编译并运行:
    gcc test.c -o test -L/path/to/library -lmy_dll
    ./test
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:25:14