rust winapi的DWORD问题记录
最近使用rust 调用winapi发现DWORD映射到rust u32十分不妥,且出现溢出现象。故作记录
在使用winapi 获得期望的数据时 DWORD最终可能会导致数值溢出。
如下面代码获取pIpForwardTable 会导致获取的dwNumEntries溢出,解决方法是自定义一个u32按字节序列读取即可
use std::env; // TODO 没法用不工作,请用别的方法 #[cfg(windows)] #[allow(non_snake_case)] fn add_route_api(ipaddr :&str,mask :&str,gw :&str,ifstr :&str) -> bool { use std::ptr::null_mut; use std::io::Write; use winapi::um::iphlpapi::{GetIpForwardTable}; use winapi::shared::ipmib::{PMIB_IPFORWARDTABLE,PMIB_IPFORWARDROW,MIB_IPFORWARDTABLE}; use winapi::shared::winerror::{ERROR_SUCCESS,ERROR_INSUFFICIENT_BUFFER}; use winapi::shared::minwindef::*; use std::{mem, ptr}; use std::convert::TryInto; let mut dwStatus :u32; let mut ipRow :PMIB_IPFORWARDROW; let mut pIpForwardTable :PMIB_IPFORWARDTABLE = null_mut(); let mut dwSize :u32 = 0; let bOrder :i32 = 1; unsafe { dwStatus = GetIpForwardTable(null_mut(), &mut dwSize, bOrder); if dwStatus == ERROR_INSUFFICIENT_BUFFER { // Allocate the memory for the table println!("### 1.{}\n",dwSize); let mut v = vec![0u8; dwSize as usize]; pIpForwardTable = v.as_mut_ptr() as PMIB_IPFORWARDTABLE ; println!("### 2. v.size:{} \n",v.len()); // Now get the table. dwStatus = GetIpForwardTable( pIpForwardTable , &mut dwSize, bOrder); println!("### 3. dwStatus: {}\n" ,dwStatus); println!("### 4. data vec: {:X?}\n" ,v); //单独取出解析 let v1 : [u8;4] = v[0..4].try_into().expect("slice with incorrect length"); let dwEntityNum = u32::from_le_bytes(v1); //小端序列 (*pIpForwardTable).dwNumEntries = dwEntityNum as DWORD; println!("### 5 dwEntityNum: {}" , (*pIpForwardTable).dwNumEntries); } if dwStatus != ERROR_SUCCESS { return false; } println!("### 5 dwEntityNum: {}" , (*pIpForwardTable).dwNumEntries); //test let mut v2: Vec<u8> = Vec::new(); let view = pIpForwardTable as *const _ as *const u8; let slice = std::slice::from_raw_parts(view, dwSize as usize) ; v2.write(slice).expect("Unable to write"); println!("{:X?}", v2); // let ff :u32 = u32::from_be_bytes( mem::transmute(pIpForwardTable) ); println!("### 6. status:{} , {}\n" , dwStatus, (*pIpForwardTable).dwNumEntries); } println!("### 7.\n"); true } fn main() { let args: Vec<String> = env::args().collect(); println!("{:?}", args); // print_message("hello world你好世界"); add_route_api("10.12.233.233", "255.255.255.255", "10.12.1.1", "1"); }