在rust-bindgen中,经常会碰到各种转换。下面是ctp bindings.rs中一个实例,这些类型需要进行转换,才方便使用。
一、常见的bindings.rs中示例
pub type TThostFtdcDateTimeType = [::std::os::raw::c_char; 17usize]; pub type TThostFtdcWeakPasswordSourceType = ::std::os::raw::c_char; pub type TThostFtdcRandomStringType = [::std::os::raw::c_char; 17usize]; pub type TThostFtdcOptSelfCloseFlagType = ::std::os::raw::c_char; pub type TThostFtdcBizTypeType = ::std::os::raw::c_char; pub type TThostFtdcAppTypeType = ::std::os::raw::c_char; pub type TThostFtdcAppIDType = [::std::os::raw::c_char; 33usize]; pub type TThostFtdcSystemInfoLenType = ::std::os::raw::c_int; pub type TThostFtdcAdditionalInfoLenType = ::std::os::raw::c_int; pub type TThostFtdcClientSystemInfoType = [::std::os::raw::c_char; 273usize]; pub type TThostFtdcAdditionalInfoType = [::std::os::raw::c_char; 261usize]; pub type TThostFtdcBase64ClientSystemInfoType = [::std::os::raw::c_char; 365usize]; pub type TThostFtdcBase64AdditionalInfoType = [::std::os::raw::c_char; 349usize]; pub type TThostFtdcCurrentAuthMethodType = ::std::os::raw::c_int;二、转换的常见方法
以下主要参考了
https://github.com/dovahcrow/xtp-rs trait FromCBuf<'a> { fn from_c_buf(b: &'a [c_char]) -> Self; } impl<'a> FromCBuf<'a> for &'a CStr { fn from_c_buf(b: &'a [c_char]) -> Self { // convert from &[i8] to &[u8] let b = unsafe { &*(b as *const _ as *const [u8]) }; match b.iter().position(|&c| c == 0u8) { Some(pos) => unsafe { CStr::from_bytes_with_nul_unchecked(&b[..=pos]) }, None => { let s = String::from_utf8(b.to_vec()); println!("{:?}", s); unreachable!("String without null end"); // to be sure follows this ! } } } } impl<'a> FromCBuf<'a> for String { fn from_c_buf(b: &'a [c_char]) -> Self { // convert from &[i8] to &[u8] let b = unsafe { &*(b as *const _ as *const [u8]) }; let slice = match b.iter().position(|&c| c == 0u8) { Some(pos) => &b[..pos], None => b, }; unsafe { String::from_utf8_unchecked(slice.to_vec()) } } } trait ToCBuf { fn to_c_buf16(&self) -> [c_char; 16usize]; fn to_c_buf64(&self) -> [c_char; 64usize]; } impl ToCBuf for &CStr { fn to_c_buf16(&self) -> [c_char; 16usize] { let mut sarr = [0i8; 16]; let len = self.to_bytes().len().min(16); for (i, &byte) in self.to_bytes()[..len].iter().enumerate() { sarr[i] = byte as i8; } sarr } fn to_c_buf64(&self) -> [c_char; 64usize] { let mut sarr = [0i8; 64]; let len = self.to_bytes().len().min(64); for (i, &byte) in self.to_bytes()[..len].iter().enumerate() { sarr[i] = byte as i8; } sarr } } impl ToCBuf for String { fn to_c_buf16(&self) -> [c_char; 16usize] { let mut sarr = [0i8; 16]; let len = self.as_bytes().len().min(16); for (i, &byte) in self.as_bytes()[..len].iter().enumerate() { sarr[i] = byte as i8; } sarr } fn to_c_buf64(&self) -> [c_char; 64usize] { let mut sarr = [0i8; 64]; let len = self.as_bytes().len().min(64); for (i, &byte) in self.as_bytes()[..len].iter().enumerate() { sarr[i] = byte as i8; } sarr } }三、具体的一些类型
比如: ::std::os::raw::c_char; =>i8 ::std::os::raw::c_int =>i32; [::std::os::raw::c_char;15usize] =>String
需要写一个脚本,把binding.rs中的内容再理一下,binding.rs中是机器翻译的,并不好用,需要转换一下,便于写代码。 这个难度不大。
四、其它类型
*mut *mut ::std::os::raw::c_char => &[&str]
五、边界值的问题 这个需要仔细考虑一下。