您的位置:首页 > 其它

Rust与C交互(FFI)中复杂类型的处理

2017-11-28 11:18 155 查看

0前言

简单类型,libc都有对应的不再赘述(没有对应的bool类型),主要是 针对 struct 和 struct 数组的交互

1内容

C类型Rust类型说明
struct_name **mut struct_namestruct指针的转换
结构体中的数组slice见具体例子
struct指针 *有两层意思:

1. 指向一个struct对象

2Rust调用C

2.1指向一个struct对象

C语言如下

struct FIParam
{
int n_min_face_size;
int n_roll_angle;
int b_only_detect;
unsigned long long reserved;
};

#define LIBDLL extern "C" _declspec(dllexport)
//函数
LIBDLL int      fi_create(short nChannelNum, FIParam* pParam);


Rust对应如下

extern crate libc;
use libc::{c_int,c_ulonglong,c_long,c_float,c_uchar,c_short};

#[repr(C)]
pub struct FIParam
{
pub n_min_face_size:c_int ,
pub n_roll_angle:c_int,
pub b_only_detect:c_int ,
pub reserved:c_ulonglong,
}
//函数
#[link(name = "库文件名(无后缀)")]
extern {
pub fn fi_create(n_channel_num:c_short,p_param: *mut FIParam) ->c_int ;
}


调用

let mut  param=Box::new(FIParam
{
n_min_face_size:80 ,
n_roll_angle:30,
b_only_detect:1 ,
reserved:0,
});

let result: i32 = unsafe {
ffi::fi_create(10 as c_short, &mut *param) as i32
};


2.2指向一个struct数组

C语言如下

struct FIPoint
{
long x;
long y;
};

struct FIFacePos
{
FIPoint     pt_left_eye;
FIPoint     pt_right_eye;
FIPoint     pt_mouth;
FIPoint     pt_nose;
FIFaceAngle f_angle;
int         n_quality;
unsigned char p_facial_data[512];//值得注意
};

#define LIBDLL extern "C" _declspec(dllexport)
//函数pfps指向的是数组
LIBDLL int      fi_detect_face(short nChannelID, int bpp, int nWidth, int nHeight, FIFacePos* pfps, int nMaxFaceNums, int nSampleSize = 640);


Rust对应

extern crate libc;
use libc::{c_int,c_ulonglong,c_long,c_float,c_uchar,c_short};
use std::mem;
#[repr(C)]
pub struct FIPoint
{
pub x:c_long,
pub y:c_long,
}
impl FIPoint{
pub fn new() -> FIPoint {
FIPoint{
x: 0 as c_long,
y: 0 as c_long,
}
}
}

#[repr(C)]
pub struct FIFacePos
{
pub pt_left_eye:FIPoint,
pub pt_right_eye:FIPoint,
pub pt_mouth:FIPoint,
pub pt_nose:FIPoint,
pub f_angle:FIFaceAngle,
pub n_quality:c_int,
pub p_facial_data:[c_uchar;512],//值得注意
}
impl FIFacePos{
pub fn new() -> FIFacePos {
FIFacePos{
pt_left_eye:FIPoint::new(),
pt_right_eye:FIPoint::new(),
pt_mouth:FIPoint::new(),
pt_nose:FIPoint::new(),
f_angle:FIFaceAngle::new(),
n_quality:0 as c_int,
p_facial_data: unsafe {mem::uninitialized()},//
}
}
}

#[link(name = "库文件名")]
extern {
pub fn fi_detect_face( n_channel_id:c_short,  bpp:c_int,  n_width:c_int,  n_height:c_int, pfps:*mut FIFacePos ,n_max_face_nums: c_int , n_sample_size:c_int )->c_int;
}


调用

extern crate libc;
use libc::{c_int,c_ulonglong,c_long,c_float,c_uchar,c_short};
use std::mem;
let max_face_num=10;
let mut face_poses = Vec::new();

for _ in 0..max_face_num {
face_poses.push(FIFacePos::new());
}
let face_num: i32 = unsafe {
fi_detect_face(0 as c_short,24 as c_int, w as c_int ,h as c_int,face_poses.as_mut_ptr(),max_face_num,640 as c_int ) as i32
};


3将Rust编译成库

3.1简单类型

Rust库

extern crate libc;

use libc::c_int;

#[no_mangle]
pub extern "C" fn rs_trigger(v1:c_int,v2:c_int) -> c_int {
return v1 + v2;
}


调用

#ifdef _WIN64
#define __EXT __declspec(dllexport)
#elif _WIN32
#define __EXT __declspec(dllexport)
#else
#define __EXT extern
#endif
//将dll拷贝到exe相同的目录
#pragma comment (lib,"**/target/release/lib**.dll.lib")

#ifdef __cplusplus
extern "C" //C++这个一定要加上
#endif
__EXT int  add(int v1, int v2);

add(1,2);


3.2复杂类型

待续

小结

只在windows 上进行测试,linux 未知
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: