4

私はかなり初心者のプログラマーで、理解していると思うが修正方法がわからない問題に直面しています。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で static functions として定義されています。これらは静的関数であり、Rust からは見ることができないと想定しています。

DPDK にバンドルされている helloworld サンプル アプリでは、rte_lcore.h を直接インポートしています。これが、librte_eal を参照するだけでなく、これらの関数にアクセスできる理由だと思いますか?

Rust でこれにアクセスする方法はありますか、またはそれらの関数をラップして FFI 経由で利用できるようにする C のシムのようなものが必要ですか?

4

1 に答える 1