如何在Rust控制台程序调用FFI函数并通过Linux终端测试?
问题描述
我有一个暴露了若干FFI函数的Rust库,已知该库可在C#中正常调用。现在需要解决两个问题:
- 如何在Rust控制台程序中正确调用这些FFI函数
- 能否通过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控制台程序的调用问题
你的代码核心问题是链接库的配置错误,按以下步骤修正:
- 修正链接属性写法
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"))]
- 确保库文件路径可被编译器找到
- 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
- 正确处理返回的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快速验证
- 安装依赖:
pip install cffi - 创建测试脚本
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}") - 运行脚本:
python test_lib.py
方法3:用C语言编写测试程序
- 创建
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; } - 编译并运行:
gcc test.c -o test -L/path/to/library -lmy_dll ./test
内容的提问来源于stack exchange,提问作者codewalker
相关产品推荐
相关产品推荐

