[英]Golang - structs, initializing and memcpy - what is the proper way?
I'm new to Go and I wish to translate some C/C++ code I have to Go but I haven't been able to. 我是Go的新手,我希望翻译一些我必须去的C / C ++代码,但我还没有做到。 The problem resides in 2 places: how can I initialize a struct I've defined and how to do a "memcopy" 问题存在两个地方:如何初始化定义的结构以及如何执行“内存复制”
The code I'm talking about is this: http://play.golang.org/p/e8N255qEAk line 69 and 74. 我正在谈论的代码是这样的: http : //play.golang.org/p/e8N255qEAk第69和74行。
The C/C++ code I wanted to "translate" to Go is this: 我想“翻译”为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 data
The Go code looks like this: Go代码如下所示:
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);
Thank you! 谢谢!
So basically given these basic types: 因此,基本上给出了以下基本类型:
type xchr int8
type xint int
type xdob float64
type xflt float32
You want to copy the bytes (memory representation) of a value of the following struct
type: 您要复制以下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
}
Note that the length of int
in Go is platform dependent, it may be 32 bit or 64 bit depending on the target architecture you compile to. 请注意,Go中int
的长度取决于平台,取决于您编译到的目标体系结构,它的长度可以是32位或64位。 That would lead to platform dependent behavior, so let's fix it to int32
for now: 这将导致平台相关的行为,所以现在让我们将其修复为int32
:
type xint int32
This is how the byte sizes of the above struct
is calculated. 这就是上述struct
的字节大小的计算方式。 If you need int64
, just change it and add 4 additional bytes in size calculation. 如果需要int64
,只需对其进行更改并在大小计算中添加4个额外的字节。
Next you want the result in an array whose element types are xchr
. 接下来,您需要将结果放入元素类型为xchr
的数组中。 You need a big enough array, which is the "prefix" being "VEH1"
followed by the data of the above struct
. 您需要一个足够大的数组,即“前缀”为"VEH1"
后跟上述struct
的数据。 So it must have a size of 4+sizeof(VEH1)
which is 56
. 因此它的大小必须为4+sizeof(VEH1)
,即56
。
In Go to copy the bytes of one type to the memory space of another type, you can do it the unsafe
package and its general Pointer
type. 在“将一种类型的字节复制到另一种类型的内存空间”中,您可以使用unsafe
包及其通用Pointer
类型来完成此操作。 Any pointer can be cast to unsafe.Pointer
and unsafe.Pointer
can be cast to any pointer type, so this is your "gateway" between different pointer types. 任何指针都可以unsafe.Pointer
unsafe.Pointer
为unsafe.Pointer
和unsafe.Pointer
可以unsafe.Pointer
unsafe.Pointer
为任何指针类型,因此这是您在不同指针类型之间的“网关”。
You can take the address of a struct
value of VHE1
, convert it to Pointer
, and convert the result Pointer
to a pointer to the target data type. 您可以采用struct
值VHE1
的地址,将其转换为Pointer
,然后将结果Pointer
转换为Pointer
目标数据类型的指针。 Dereference the pointer and now you already have the value of the other type. 取消引用指针,现在您已经具有其他类型的值。
The builtin copy()
can only be used with slices, so first you need to slice your data arrays to be able to pass them to copy()
. 内置的copy()
只能与slice一起使用,因此首先您需要对数据数组进行切片,以便将它们传递给copy()
。
You can do it like this: 您可以这样做:
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)
Output, wrapped to fit in screen: 包装成适合屏幕的输出:
{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]
Try the working demo on the Go Playground . 在Go Playground上尝试运行的演示。
[]byte
结果为[]byte
If you want []byte
result (eg you want to write the result to an io.Writer
), then use [56]byte
type for data_send
and of course cast pavio
to *[52]byte
: 如果您想要[]byte
结果(例如,您要将结果写入io.Writer
),则对data_send
使用[56]byte
类型,当然将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[:])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.