Rust 如何获取下一个指针?

Rust 如何获取下一个指针?,rust,raw-pointer,Rust,Raw Pointer,我有一个用C实现的函数,我想用Rust编写一个具有相同接口的函数。函数接收指向数组开头(win8\u 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;

我有一个用C实现的函数,我想用Rust编写一个具有相同接口的函数。函数接收指向数组开头(
win8\u 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
}
使用std::mem;
酒吧外部“C”fn下一页打印(i:*常数u8){
设mut ii=unsafe{mem::transmute::(i)};
ii+=1;
设iii=不安全{mem::transmute::(ii)};
设jj=unsafe{*iii};
println!(“{}”,jj);//jj是下一个值
}

正如Shepmaster所说,您可能需要提供切片的长度

大多数时候,使用指针时,函数都是不安全的(因为通常需要在某个点取消对它的引用)。最好将其标记为不安全,以便将安全责任委托给来电者

下面是一些使用
偏移量
自原始切片
的示例:

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
    }
}
使用std::mem;
使用std::slice;
//不安全!
酒吧外部“C”fn下一页打印(i:*常数u8){
设mut ii=unsafe{mem::transmute::(i)};
ii+=1;
设iii=不安全{mem::transmute::(ii)};
设jj=unsafe{*iii};
println!(“{}”,jj);//jj是下一个值
}
//不安全!
酒吧不安全外部“C”fn打印下一页2(i:*常数u8){
设j=*i.偏移量(1);
println!(“{}”,j);
}
//(更少但仍然…)不安全!
酒吧不安全外部“C”fn打印(i:*常数u8,len:usize){
let slice=slice::from_raw_parts(i,len);
//我们没有检查尺寸…所以它可能会恐慌!
println!(“{}”,切片[1]);
}
fn main(){
设a=[9u8,4,6,7];
下一步打印(&a为*常量u8);
不安全{
打印下一页2(&a[1]为*常量u8);
打印下一页3(&a[2]为*常量u8,2);
}
//如果我打印的东西不是在一个??
打印_next(&a[3]为*const u8);//错误
不安全{
打印_next2(&a[3]为*const u8);//错误
打印_next3(&a[3]为*const u8,2);//与其他文件一样糟糕,长度错误
打印_next3(&a[3]为*const u8,1);//恐慌!超出范围
}
}

正如Shepmaster所说,您可能需要提供切片的长度

大多数时候,使用指针时,函数都是不安全的(因为通常需要在某个点取消对它的引用)。最好将其标记为不安全,以便将安全责任委托给来电者

下面是一些使用
偏移量
自原始切片
的示例:

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
    }
}
使用std::mem;
使用std::slice;
//不安全!
酒吧外部“C”fn下一页打印(i:*常数u8){
设mut ii=unsafe{mem::transmute::(i)};
ii+=1;
设iii=不安全{mem::transmute::(ii)};
设jj=unsafe{*iii};
println!(“{}”,jj);//jj是下一个值
}
//不安全!
酒吧不安全外部“C”fn打印下一页2(i:*常数u8){
设j=*i.偏移量(1);
println!(“{}”,j);
}
//(更少但仍然…)不安全!
酒吧不安全外部“C”fn打印(i:*常数u8,len:usize){
let slice=slice::from_raw_parts(i,len);
//我们没有检查尺寸…所以它可能会恐慌!
println!(“{}”,切片[1]);
}
fn main(){
设a=[9u8,4,6,7];
下一步打印(&a为*常量u8);
不安全{
打印下一页2(&a[1]为*常量u8);
打印下一页3(&a[2]为*常量u8,2);
}
//如果我打印的东西不是在一个??
打印_next(&a[3]为*const u8);//错误
不安全{
打印_next2(&a[3]为*const u8);//错误
打印_next3(&a[3]为*const u8,2);//与其他文件一样糟糕,长度错误
打印_next3(&a[3]为*const u8,1);//恐慌!超出范围
}
}

接收指针[…]和长度-您的函数只接受一个参数。过程中是否丢失了一些内容?如果包含C函数的一个参数,这将非常有用。的可能副本接收指针[…]和长度-您的函数只接受一个参数。有什么东西在过程中丢失了吗?如果你包含C函数的一部分,这将非常有用。
print\u next3
的可能重复是我宣传的“正确”解决方案,尽管OP没有要求它。这是因为它将不安全性集中到一个点:调用
slice::from\u raw\u parts
。在这之后,Rust将负责安全性,并且,只要调用者没有谎报数据的位置和长度,一切都将是安全的。调用方建议的API受C设计的影响,其中指针算法是自然产生的。在Rust中,您希望首先获得一个正确的检查切片,然后执行其他所有操作。
print_next3
是我宣传的“正确”解决方案,尽管OP没有要求它。这是因为它将不安全性集中到一个点:调用
slice::from\u raw\u parts
。在这之后,Rust将负责安全性,并且,只要调用者没有谎报数据的位置和长度,一切都将是安全的。调用方建议的API受C设计的影响,其中指针算法是自然产生的。在锈病中,你需要先得到一个合适的检查切片,然后再做其他的事情。