Rust与C交互(FFI)中复杂类型的处理
2017-11-28 11:18
155 查看
0前言
简单类型,libc都有对应的不再赘述(没有对应的bool类型),主要是 针对 struct 和 struct 数组的交互1内容
C类型 | Rust类型 | 说明 |
---|---|---|
struct_name * | *mut struct_name | struct指针的转换 |
结构体中的数组 | slice | 见具体例子 |
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 未知相关文章推荐
- CXF webservice JAXB 处理复杂数据类型方法
- fastjson:对于Exception中复杂类型(enum,...以及自定义类型)成员的处理
- WebAPI 传递复杂类型处理绑定模型
- Jackson 处理复杂类型(List,map)两种方法
- Xfire处理复杂类型的方法
- JSP自定义标签_属性接收复杂类型处理方式
- Jackson 处理复杂类型(List,map)两种方法
- J2EE下使用AJAX(六) 后记以及如何处理复杂的返回值类型
- 【WebService】CXF处理javaBean等复合类型以及Map等复杂类型的数据
- 在Axis中处理复杂的自定义的数据类型
- CXF 处理一些Map 等复杂类型
- Jackson 处理复杂类型(List,map)两种方法
- jackson 自定义解析类,处理复杂类型
- CXF--处理复杂类型
- Jackson 处理复杂类型(List,map)
- 【WebService】CXF处理javaBean等复合类型以及Map等复杂类型的数据
- cxf处理一些Map等复杂类型
- 6.Web Service CXF处理一些Map等复杂类型
- WS之cxf处理的复杂类型(Map)
- J2EE AJAX(六) 如何处理复杂的返回值类型