我是Go的新手,我希望翻译一些我必须去的C / C ++代码,但我还没有。问题在于两个地方:如何初始化我已定义的结构以及如何进行" memcopy"
我正在谈论的代码是:http://play.golang.org/p/e8N255qEAk 第69和74行。
我想要的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
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);
谢谢!
答案 0 :(得分: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
}
请注意,Go中int
的长度取决于平台,可能是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
结果(例如,您想将结果写入io.Writer
),请使用[56]byte
类型data_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[:])