将内存转换为结构体的golang类型转换

3

我正在将遗留代码移植到Go语言中,该代码具有高性能,但我在翻译程序的一部分时遇到了困难,该部分需要读取共享内存以供日后解析。

在C语言中,我只需将内存强制转换为结构体并正常访问即可。

在Go语言中,最有效且符合惯用法的方法是什么?


你能否发布你想要翻译的代码,这样我们就可以大致了解你的问题是什么? - fuz
1个回答

9
如果你想将字节数组转换为结构体,可以使用unsafe包来实现。这里有一个可用的示例
但是,这种方法有一些限制,只能使用特定的结构体字段类型。除非你的C代码恰好产生与相应切片/字符串头部的内存布局完全相同的结果,否则无法使用切片和字符串。如果仅涉及固定大小的数组和(u)int(8/16/32/64)类型,则下面的代码可能足够。否则,您需要手动复制和分配每个结构体字段。
package main

import "fmt"
import "unsafe"

type T struct {
    A uint32
    B int16
}

var sizeOfT = unsafe.Sizeof(T{})

func main() {
    t1 := T{123, -321}
    fmt.Printf("%#v\n", t1)

    data := (*(*[1<<31 - 1]byte)(unsafe.Pointer(&t1)))[:sizeOfT]
    fmt.Printf("%#v\n", data)

    t2 := (*(*T)(unsafe.Pointer(&data[0])))
    fmt.Printf("%#v\n", t2)
}

请注意,(*[1<<31 - 1]byte) 实际上并不会分配这么大的字节数组。这是一个技巧,用于确保可以通过 ...[:sizeOfT] 部分创建正确大小的切片。大小为 1<<31 - 1 是 Go 中任何切片可能拥有的最大大小。至少在过去是这样的。我不确定现在是否仍然适用。无论如何,您必须使用这种方法来获取正确大小的字节切片。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接