CGO中Golang切片传递给Rust出现数据异常,如何解决?
问题解决:Go与Rust跨语言调用uint切片数据异常
问题根源
输出出现[1,0,2,0,3,0]的核心原因是类型宽度不匹配:
- Go的
uint是平台相关类型,64位系统下为64位(8字节); - Rust侧用
u32(固定32位/4字节)解析内存,导致把单个64位的Gouint拆成两个32位值,高4字节补0,最终出现交替0的异常数据。
解决方案:统一类型宽度
将Go侧的切片类型改为固定32位的uint32,与Rust的u32严格对齐,同时同步C头文件的类型定义以明确约束。
修改后的代码
Go代码
input := []uint32{1,2,3,4,5,6} o := C.fixU32_encode((*C.uint32_t)(unsafe.Pointer(&input[0])), C.size_t(len(input))) return C.GoString(o)
C头文件(引入stdint.h保证类型宽度)
#include <stdint.h> char* fixU32_encode(uint32_t* ptr, size_t length);
Rust代码(无需修改,u32与uint32_t内存布局完全一致)
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); 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() }
关键注意事项
跨语言调用时,必须避免使用平台相关的数值类型(如Go的uint/int、C的unsigned int/int),优先使用固定宽度类型(如uint32_t/u32、int64_t/i64),确保不同语言间的内存解析逻辑完全一致。
内容的提问来源于stack exchange,提问作者hahaming
相关产品推荐
相关产品推荐

