Accessing Static C Functions in DPDK from Rust FFI

I am a pretty novice programmer, and I am facing a problem that I think I understand, but don’t know how to fix. I'm trying to use Rust FFI to interact with Intel DPDK , which is all in C. My first attempt is to recreate the helloworld example application.

I get a compilation error, which, in my opinion, is due to the fact that the functions from DPDK are static and are not directly accessible from the library. My FFI interface is here:

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;
}

I also have a library referencing this and wrapping functions:

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
}

And the build.rs file for linking the libraries is

//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, undefined rte_lcore_id rte_get_next_lcore. API DPDK, librte_eal, rte_lcore.h . , , Rust.

helloworld, DPDK, rte_lcore.h. , librte_eal?

Rust - C, FFI?

+4
1

, , . , .c/.cpp, , static, , . , , , , FFI.

, stub C, , , . :

#include <rte_lcore.h>

unsigned my_rte_lcore_count(void) {
    return rte_lcore_count();
}

// and so forth for every function you need

, Makefile, Cargo build script, . , , extern, :

extern {
    fn my_rte_lcore_count() -> libc::c_uint;
}

, .

: , . , , .

+6

All Articles