为了账号安全,请及时绑定邮箱和手机立即绑定

Golang - 结构、初始化和 memcpy - 正确的方法是什么?

Golang - 结构、初始化和 memcpy - 正确的方法是什么?

Go
缥缈止盈 2021-10-18 10:31:51
我是 Go 的新手,我希望翻译一些我必须去的 C/C++ 代码,但我一直没能做到。问题存在于 2 个地方:如何初始化我定义的结构以及如何执行“memcopy”我正在谈论的代码是这样的:http : //play.golang.org/p/e8N255qEAk 第 69 和 74 行。我想“翻译”到 Go 的 C/C++ 代码是这样的:            typedef char xchr;            typedef int xint;            typedef double xdob;            typedef float xflt;            typedef struct            {               xint p;                xdob lat_lon_ele[3];               xflt psi_the_phi[3];               xflt gear_flap_vect[3];            }VEH1;            avio.p = 0;            avio.lat_lon_ele[0] = 47.460058;            avio.lat_lon_ele[1] = -122.32104;            avio.lat_lon_ele[2] = 8000.000;            avio.psi_the_phi[0] = 110.5;            avio.psi_the_phi[1] = 0.0;            avio.psi_the_phi[2] = 0.0;            avio.gear_flap_vect[0] = 1.0;            avio.gear_flap_vect[1] = 0.0;            avio.gear_flap_vect[2] = 0.0;            VEH1* av = &avio;            xchr data_send[6];            data_send[0]='V';            data_send[1]='E';            data_send[2]='H';            data_send[3]='1';            data_send[4]=0;            memcpy(&data_send[5],av,sizeof(VEH1)); // load in the dataGo 代码如下所示:            type xchr int8            type xint int            type xdob float64            type xflt float32            type VEH1 struct {                p              xint                lat_lon_ele    [3]xdob                psi_the_phi    [3]xflt                gear_flap_vect [3]xflt            }            type VEHA struct {                num_p xint                lat_lon_ele    [10][3]xdob                psi_the_phi    [10][3]xflt                gear_flap_vect [10][3]xflt                lat_view, lon_view, ele_view xdob                psi_view, the_view, phi_view xflt            }            var avio VEH1            avio = &VEH1{0, {47.460058, -122.32104, 8000.000}, {110.5, 0.0, 0.0}, {1.0, 0.0, 0.0}}            data_send := [6]xchr{'V', 'E', 'H', '1', 0, 0}            copy(data_send[5:5], avio);谢谢!
查看完整描述

1 回答

?
森林海

TA贡献2011条经验 获得超2个赞

所以基本上给出了这些基本类型:


type xchr int8

type xint int

type xdob float64

type xflt float32

您想要复制以下struct类型值的字节(内存表示):


type VEH1 struct { // 52 bytes total

    p              xint    // 4 bytes (READ BELOW)

    lat_lon_ele    [3]xdob // 24 bytes

    psi_the_phi    [3]xflt // 12 bytes

    gear_flap_vect [3]xflt // 12 bytes

}

请注意,intGo中的长度取决于平台,它可能是 32 位或 64 位,具体取决于您编译到的目标架构。这将导致平台相关行为,所以让我们暂时将其修复int32为:


type xint int32

这就是上述字节大小的struct计算方式。如果需要int64,只需更改它并在大小计算中添加 4 个额外字节。


接下来,您需要元素类型为 的数组中的结果xchr。您需要一个足够大的数组,即“前缀”"VEH1"后跟上面的数据struct。所以它的大小必须4+sizeof(VEH1)是56。


在 Go 中将一种类型的字节复制到另一种类型的内存空间中,可以将其unsafe封装及其通用Pointer类型。任何指针都可以转换为unsafe.Pointer并且unsafe.Pointer可以转换为任何指针类型,因此这是不同指针类型之间的“网关”。


您可以获取 的struct值的地址VHE1,将其转换为Pointer,并将结果转换Pointer为指向目标数据类型的指针。取消引用指针,现在您已经拥有其他类型的值。


内置copy()函数只能与切片一起使用,因此首先您需要对数据数组进行切片以便能够将它们传递给copy().


你可以这样做:


avio := VEH1{0, [3]xdob{47.460058, -122.32104, 8000.000},

    [3]xflt{110.5, 0.0, 0.0}, [3]xflt{1.0, 0.0, 0.0}}

fmt.Printf("%+v\n", avio)


pavio := unsafe.Pointer(&avio)

pavio_arr := *((*[52]xchr)(pavio))


data_send := [56]xchr{'V', 'E', 'H', '1'}

n := copy(data_send[4:], pavio_arr[:])

fmt.Printf("Copied %d bytes\n", n)


fmt.Printf("%+v\n", data_send)

输出,包装以适应屏幕:


{p:0 lat_lon_ele:[47.460058 -122.32104 8000] psi_the_phi:[110.5 0 0]

    gear_flap_vect:[1 0 0]}

Copied 52 bytes

[86 69 72 49 0 0 0 0 0 0 0 0 -81 33 56 46 -29 -70 71 64 77 45 91 -21 -117

    -108 94 -64 0 0 0 0 0 64 -65 64 0 0 -35 66 0 0 0 0 0 0 0 0 0 0 -128 63 0 0 0 0]

在Go Playground上尝试工作演示。


结果为 []byte

如果您想要[]byte结果(例如,您想将结果写入 an io.Writer),则使用[56]byte类型 fordata_send并且当然强制转换pavio为*[52]byte:


pavio := unsafe.Pointer(&avio)

pavio_arr := *((*[52]byte)(pavio))


data_send := [56]byte{'V', 'E', 'H', '1'}

n := copy(data_send[4:], pavio_arr[:])


查看完整回答
反对 回复 2021-10-18
  • 1 回答
  • 0 关注
  • 289 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信