CGO how to pass slice to rust

huangapple go评论83阅读模式
英文:

CGO how to pass slice to rust

问题

golang

input := []uint{1,2,3,4,5,6}
o := C.fixU32_encode((*C.uint)(unsafe.Pointer(&input[0])), C.size_t(len(input)))
return C.GoString(o)

c

char* fixU32_encode(unsigned int* ptr,size_t length);

rust

pub extern "C" fn fixU32_encode(ptr: *const u32, length: libc::size_t) -> *const libc::c_char {
    assert!(!ptr.is_null());
    let slice = unsafe {
        std::slice::from_raw_parts(ptr, length as usize)
    };
    println!("{:?}", slice);// there will print [1,0,2,0,3,0]
    println!("{:?}", length);
    let mut arr = [0u32; 6];
    for (&x, p) in slice.iter().zip(arr.iter_mut()) {
        *p = x;
    }
    CString::new(hex::encode(arr.encode())).unwrap().into_raw()
}

这段代码将被传入,但是rust接收到的数组是这样的
[1,0,2,0,3,0]

英文:

golang

input := []uint{1,2,3,4,5,6}
o := C.fixU32_encode((*C.uint)(unsafe.Pointer(&input[0])), C.size_t(len(input)))
return C.GoString(o)

c

char* fixU32_encode(unsigned int* ptr,size_t length);

rust

pub extern "C" fn fixU32_encode(ptr: *const u32, length: libc::size_t) -> *const libc::c_char {
    assert!(!ptr.is_null());
    let slice = unsafe {
        std::slice::from_raw_parts(ptr, length as usize)
    };
    println!("{:?}", slice);// there will print [1,0,2,0,3,0]
    println!("{:?}", length);
    let mut arr = [0u32; 6];
    for (&x, p) in slice.iter().zip(arr.iter_mut()) {
        *p = x;
    }
    CString::new(hex::encode(arr.encode())).unwrap().into_raw()
}

This will be passed in, but the array received by rust is like this
[1,0,2,0,3,0]

答案1

得分: 2

在Go语言中,uint是64位的(参见https://golangbyexample.com/go-size-range-int-uint/)。因此,你正在将64位整数存储在input中。

C代码和Rust代码将input视为32位无符号整数(以小端格式)。因此,64位中的第一个输入0x1:

00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001

在C代码和Rust代码中分别变为0x1和0x0。由于小端格式,最低有效位先被读取。

如果你想在Go中明确使用32位,请使用uint32,或确保你的C代码与Go中的机器相关整数类型匹配。

英文:

In Go an uint is 64bit (see https://golangbyexample.com/go-size-range-int-uint/). As a result, you are storing 64bit integers in input.

The C Code and Rust code treats the input now was 32bit unsigned integers (in little endian format). So the first input of 0x1 in 64bit:

00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001

becomes 0x1 and 0x0 respectively. Due to little endian the least significant bits are read first.

You want to be specific in Go to use 32bit using uint32 or ensure your C code matches the machine dependent integers types in Go.

huangapple
  • 本文由 发表于 2022年7月16日 19:34:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/73003860.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定