a fast c-style struct packer & unpacker for golang
- Go struct 与 C struct 一一对应,内存分布一致。
- 快速。
- 方便,只需要定义 struct 即可。
-
定义举例
type mystruct1 struct { F1 bool F2 float32 F3 float64 F4 string F5 []byte F6 int8 F7 int16 F9 int32 F11 int64 F12 uint8 F13 uint16 F15 uint32 F17 uint64 F18 [20]byte F19 [16]uint32 }
-
使用举例
a := &mystruct1{} // ...(初始化a 代码略)... // 序列化代码如下,返回 []byte类型数据 buf_l, _ := cstruct.Marshal(a) // 反序列化代码如下 b := &mystruct1{} if err := cstruct.Unmarshal(buf_l, b); err != nil { fmt.Println(err) return }
详细例子可以参考:
演示 C struct 与 Go struct 内存分布一致
-
C struct:
#include <string> #pragma pack(1) struct StructA { uint8_t A1; uint32_t A2; uint8_t A3[5]; }; struct StructB { uint8_t B1; StructA B2; uint16_t B3; float B4; StructA B5[3]; }; int main() { StructB b; b.B1 = 127; b.B2.A1 = 56; b.B2.A2 = 999; b.B2.A3[0] = 0; b.B2.A3[1] = 1; b.B2.A3[2] = 2; b.B2.A3[3] = 3; b.B2.A3[4] = 4; b.B3 = 8888; b.B4 = 88.8f; b.B5[0] = b.B2; b.B5[1] = b.B2; b.B5[2] = b.B2; printf("len(b) = %llu\n", sizeof(b)); printf("struct data len = %llu\n", sizeof(b)); printf("struct data is:\n"); unsigned char buff[1024]; memcpy(buff, &b, sizeof(b)); for (int i = 0; i < sizeof(b); i++) { printf("%d ", buff[i]); } return 0; }
-
Go struct
type StructA struct { A1 uint8 A2 uint32 A3 [5]uint8 } type StructB struct { B1 uint8 B2 StructA B3 uint16 B4 float32 B5 [3]StructA } func main() { b := StructB{} b.B1 = 127 b.B2.A1 = 56 b.B2.A2 = 999 b.B2.A3[0] = 0 b.B2.A3[1] = 1 b.B2.A3[2] = 2 b.B2.A3[3] = 3 b.B2.A3[4] = 4 b.B3 = 8888 b.B4 = 88.8 b.B5[0] = b.B2 b.B5[1] = b.B2 b.B5[2] = b.B2 data, _ := cstruct.Marshal(&b) fmt.Println("len(b) =", unsafe.Sizeof(b)) fmt.Println("struct data len = ", len(data)) fmt.Println("struct data is:") for i := 0; i < len(data); i++ { fmt.Printf("%d ", data[i]) } }
-
以上控制台输出
D:\golang\src\github.com\fananchong\cstruct-go\example>main.exe len(b) = 76 struct data len = 47 struct data is: 127 56 231 3 0 0 0 1 2 3 4 184 34 154 153 177 66 56 231 3 0 0 0 1 2 3 4 56 231 3 0 0 0 1 2 3 4 56 231 3 0 0 0 1 2 3 4 D:\golang\src\github.com\fananchong\cstruct-go\example>main_cpp.exe len(b) = 47 struct data len = 47 struct data is: 127 56 231 3 0 0 0 1 2 3 4 184 34 154 153 177 66 56 231 3 0 0 0 1 2 3 4 56 231 3 0 0 0 1 2 3 4 56 231 3 0 0 0 1 2 3 4
-
详细例子可以参考:
小端
字节序。
go类型 | 内存说明 |
---|---|
bool | 1 byte |
int8 | 1 byte |
uint8 | 1 byte |
int16 | 2 byte |
uint16 | 2 byte |
int32 | 4 byte |
uint32 | 4 byte |
int64 | 8 byte |
uint64 | 8 byte |
float32 | 4 byte |
float64 | 8 byte |
string | [2 byte] + [len(字符串) byte] |
[]byte | [2 byte] + [len(2进制数据) byte] |
- 支持基本类型的数组(string 、 []byte 除外,因为它们不定长)
- 支持定长struct的数组
- 支持struct指针(默认格式)
go类型 | 内存说明 | byte含义说明 |
---|---|---|
struct ptr | [1 byte] + [len(struct内存占用) byte] | 1byte值为0,表示指针为nil |
- 支持struct指针(当 cstruct.OptionSliceIgnoreNil = true )
go类型 | 内存说明 |
---|---|
struct ptr | [len(struct内存占用) byte] |
- 支持struct嵌套
- 支持基本类型的Slice
- 支持struct指针的Slice
- 支持struct的Slice
go类型 | 内存说明 |
---|---|
slice | [2 byte] + [len(元素内存占用) byte] |
测试环境:阿里云ECS服务器,配置: 1 vCPU 2 GB (I/O优化) ecs.t5-lc1m2.small 1Mbps
基准测试代码:cstrucgo_test.go