2017-05-01 50 views
0

我有一個用C語言實現的函數,我想用Rust接口寫一個函數。該函數接收一個指向數組開頭(win8_t *)和數組長度的指針。我需要能夠遍歷數組。如何獲得下一個指針?

必須有一個更好的方式來獲得下一個值,但現在我可以做這個奇怪的事情:

use std::mem; 
pub extern "C" fn print_next(i: *const u8) { 
    let mut ii = unsafe { mem::transmute::<*const u8, i64>(i) }; 
    ii += 1; 
    let iii = unsafe { mem::transmute::<i64, *const u8>(ii) }; 
    let jj = unsafe { *iii }; 
    println!("{}", jj); // jj is next value 
} 
+1

*接收指向[...] **和長度*** - 你的函數只接受一個參數。一路上有東西迷路了嗎? – Shepmaster

+1

如果包含C函數的[MCVE],它將*非常有用。 – Shepmaster

+3

[你應該如何在Rust中做指針運算?](http://stackoverflow.com/questions/24759028/how-should-you-do-pointer-arithmetic-in-rust) – kennytm

回答

1

正如Shepmaster說,你可能需要提供片的長度。

大多數時候你正在使用指針,你的函數將是不安全的(因爲你通常需要在某些時候解引用它)。將他們安全責任委派給調用者是不安全的,這可能是一個好主意。

下面是使用offsetfrom_raw_slice一些例子:

use std::mem; 
use std::slice; 

// unsafe! 
pub extern "C" fn print_next(i: *const u8) { 
    let mut ii = unsafe { mem::transmute::<*const u8, i64>(i) }; 
    ii += 1; 
    let iii = unsafe { mem::transmute::<i64, *const u8>(ii) }; 
    let jj = unsafe { *iii }; 
    println!("{}", jj); // jj is next value 
} 

// unsafe! 
pub unsafe extern "C" fn print_next2(i: *const u8) { 
    let j = *i.offset(1); 
    println!("{}", j); 
} 

// (less but still ...) unsafe! 
pub unsafe extern "C" fn print_next3(i: *const u8, len: usize) { 
    let slice = slice::from_raw_parts(i, len); 
    // we are not checking the size ... so it may panic! 
    println!("{}", slice[1]); 
} 

fn main() { 
    let a = [9u8, 4, 6, 7]; 
    print_next(&a as *const u8); 
    unsafe { 
     print_next2(&a[1] as *const u8); 
     print_next3(&a[2] as *const u8, 2); 
    } 

    // what if I print something not in a?? 
    print_next(&a[3] as *const u8); // BAD 
    unsafe { 
     print_next2(&a[3] as *const u8); // BAD 
     print_next3(&a[3] as *const u8, 2); // as bad as others, length is wrong 

     print_next3(&a[3] as *const u8, 1); // panic! out of bounds 
    } 
} 
+1

'print_next3'是什麼儘管OP沒有提出要求,我還是會做廣告作爲「適當的」解決方案。這是因爲它將不安全性集中在一個地方:對slice :: from_raw_parts的調用。在此之後,Rust會照顧到安全,並且只要呼叫者沒有說謊數據的位置和長度,一切都將是安全的。調用者建議的API受到C設計的影響,其中指針算術是自然而然的。在Rust中,你首先需要得到一個適當的檢查切片,然後做其他事情。 – user4815162342