我是一个相当新手的程序员,遇到了我认为我理解但不知道如何解决的问题。我试图使用Rust FFI与C语言中的Intel DPDK进行交互。我的第一个尝试是重新创建helloworld示例应用程序。
我遇到了一个编译错误,我认为这是由于DPDK中的函数是静态的,并且不能直接从库中获得。我的FFI界面在这里:
use libc::{c_uint, c_int, c_void, c_char}; pub type LcoreFunctionT = extern "C" fn(arg1: *mut c_void) -> c_int; extern { pub fn rte_eal_init(argc: c_int, argv: *mut *mut c_char) -> c_int; pub fn rte_eal_remote_launch(f: *mut LcoreFunctionT, arg: *mut c_void, slave_id: c_uint) -> c_int; pub fn rte_eal_mp_wait_lcore() -> (); pub fn rte_lcore_id() -> c_uint; pub fn rte_get_next_lcore(i: c_uint, skip_master: c_int, wrap: c_int) -> c_uint; }
我也有一个库对此进行引用并包装了这些函数:
extern crate libc; use libc::{c_uint, c_int, c_char, c_void}; use std::ffi::CString; use std::ptr; mod ffi_rte_eal; pub fn dpdk_rte_eal_init(argc: i32, argv: Vec<String>) -> i32 { let mut args: Vec<*mut c_char> = argv.iter().map(|x| CString::new(x.clone()).unwrap().into_raw()).collect(); let retc: c_int = unsafe {ffi_rte_eal::rte_eal_init(argc as c_int, args.as_mut_ptr())}; let ret: i32 = retc as i32; ret } pub fn dpdk_rte_eal_remote_launch(f: extern "C" fn(*mut c_void) -> i32, slave_id: u32 ) -> i32 { let mut fc: ffi_rte_eal::LcoreFunctionT = f; let retc: c_int = unsafe {ffi_rte_eal::rte_eal_remote_launch(&mut fc, ptr::null_mut() as *mut c_void, slave_id as c_uint)}; let ret: i32 = retc as i32; ret } pub fn dpdk_rte_eal_mp_wait_lcore() -> (){ unsafe { ffi_rte_eal::rte_eal_mp_wait_lcore(); } } pub fn dpdk_rte_lcore_id() -> u32 { let retc: c_uint = unsafe {ffi_rte_eal::rte_lcore_id()}; let ret: u32 = retc as u32; ret } pub fn dpdk_rte_get_next_lcore(i: u32, skip_master: i32, wrap: i32) -> u32 { let retc: c_uint = unsafe {ffi_rte_eal::rte_get_next_lcore(i as c_uint, skip_master as c_int, wrap as c_int)}; let ret: u32 = retc as u32; ret }
还有一个build.rs文件,用于链接库-
//build.rs fn main() { println!("cargo:rustc-link-lib=static=rte_eal"); println!("cargo:rustc-link-search=native=/usr/local/lib"); println!("cargo:rustc-link-lib=static=rte_mempool"); println!("cargo:rustc-link-search=native=/usr/local/lib"); println!("cargo:rustc-link-lib=static=rte_ring"); println!("cargo:rustc-link-search=native=/usr/local/lib"); }
当我尝试编译我自己对FFI接口应用,我把即将未定义的引用收到错误rte_lcore_id和rte_get_next_lcore。根据DPDK的API文档,这些函数是librte_eal库的一部分,但在rte_lcore.h中定义为静态函数。我假设这些是静态函数,我将无法从Rust看到它们。
在与DPDK捆绑在一起的helloworld示例应用程序中,它们直接导入rte_lcore.h。我认为这就是为什么他们可以不参考librte_eal而访问这些功能的原因?
是否有一种方法可以在Rust中访问此函数,还是必须有类似C的填充程序这样的东西才能让我包装这些函数并通过FFI使它们可用?