gitee.com/quant1x/gox@v1.21.2/encoding/binary/cstruct/README.md (about) 1 # cstruct-go 2 3 a fast c-style struct packer & unpacker for golang 4 5 6 ## 特性 7 8 - Go struct 与 C struct 一一对应,内存分布一致。 9 - 快速。 10 - 方便,只需要定义 struct 即可。 11 12 13 ## 例子1 14 15 1. 定义举例 16 17 ```go 18 type mystruct1 struct { 19 F1 bool 20 F2 float32 21 F3 float64 22 F4 string 23 F5 []byte 24 F6 int8 25 F7 int16 26 F9 int32 27 F11 int64 28 F12 uint8 29 F13 uint16 30 F15 uint32 31 F17 uint64 32 F18 [20]byte 33 F19 [16]uint32 34 } 35 ``` 36 37 2. 使用举例 38 39 ```go 40 a := &mystruct1{} 41 // ...(初始化a 代码略)... 42 43 // 序列化代码如下,返回 []byte类型数据 44 buf_l, _ := cstruct.Marshal(a) 45 46 // 反序列化代码如下 47 b := &mystruct1{} 48 if err := cstruct.Unmarshal(buf_l, b); err != nil { 49 fmt.Println(err) 50 return 51 } 52 ``` 53 54 详细例子可以参考: 55 56 - [x_test.go](tests/x_test.go) 57 - [array_test.go](tests/array_test.go) 58 59 60 ## 例子2 61 62 演示 C struct 与 Go struct 内存分布一致 63 64 - C struct: 65 66 ```c++ 67 #include <string> 68 69 #pragma pack(1) 70 71 struct StructA { 72 uint8_t A1; 73 uint32_t A2; 74 uint8_t A3[5]; 75 }; 76 77 78 struct StructB { 79 uint8_t B1; 80 StructA B2; 81 uint16_t B3; 82 float B4; 83 StructA B5[3]; 84 }; 85 86 int main() 87 { 88 StructB b; 89 b.B1 = 127; 90 b.B2.A1 = 56; 91 b.B2.A2 = 999; 92 b.B2.A3[0] = 0; 93 b.B2.A3[1] = 1; 94 b.B2.A3[2] = 2; 95 b.B2.A3[3] = 3; 96 b.B2.A3[4] = 4; 97 b.B3 = 8888; 98 b.B4 = 88.8f; 99 b.B5[0] = b.B2; 100 b.B5[1] = b.B2; 101 b.B5[2] = b.B2; 102 103 printf("len(b) = %llu\n", sizeof(b)); 104 printf("struct data len = %llu\n", sizeof(b)); 105 printf("struct data is:\n"); 106 107 unsigned char buff[1024]; 108 memcpy(buff, &b, sizeof(b)); 109 for (int i = 0; i < sizeof(b); i++) { 110 printf("%d ", buff[i]); 111 } 112 return 0; 113 } 114 ``` 115 116 - Go struct 117 118 ```golang 119 type StructA struct { 120 A1 uint8 121 A2 uint32 122 A3 [5]uint8 123 } 124 125 type StructB struct { 126 B1 uint8 127 B2 StructA 128 B3 uint16 129 B4 float32 130 B5 [3]StructA 131 } 132 133 func main() { 134 b := StructB{} 135 b.B1 = 127 136 b.B2.A1 = 56 137 b.B2.A2 = 999 138 b.B2.A3[0] = 0 139 b.B2.A3[1] = 1 140 b.B2.A3[2] = 2 141 b.B2.A3[3] = 3 142 b.B2.A3[4] = 4 143 b.B3 = 8888 144 b.B4 = 88.8 145 b.B5[0] = b.B2 146 b.B5[1] = b.B2 147 b.B5[2] = b.B2 148 149 data, _ := cstruct.Marshal(&b) 150 151 fmt.Println("len(b) =", unsafe.Sizeof(b)) 152 fmt.Println("cstruct data len = ", len(data)) 153 fmt.Println("cstruct data is:") 154 for i := 0; i < len(data); i++ { 155 fmt.Printf("%d ", data[i]) 156 } 157 } 158 ``` 159 160 - 以上控制台输出 161 162 ```shell 163 D:\golang\src\github.com\fananchong\ccstruct-go\example>main.exe 164 len(b) = 76 165 cstruct data len = 47 166 cstruct data is: 167 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 168 D:\golang\src\github.com\fananchong\ccstruct-go\example>main_cpp.exe 169 len(b) = 47 170 cstruct data len = 47 171 cstruct data is: 172 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 173 ``` 174 175 - 详细例子可以参考: 176 - [example](example) 177 178 179 ## 字节序 180 181 `小端`字节序。 182 183 ## 基本类型 184 185 go类型 | 内存说明 186 ------- | ---------------------------- 187 bool | 1 byte 188 int8 | 1 byte 189 uint8 | 1 byte 190 int16 | 2 byte 191 uint16 | 2 byte 192 int32 | 4 byte 193 uint32 | 4 byte 194 int64 | 8 byte 195 uint64 | 8 byte 196 float32 | 4 byte 197 float64 | 8 byte 198 string | [2 byte] + [len(字符串) byte] 199 []byte | [2 byte] + [len(2进制数据) byte] 200 201 202 ## 数组类型 203 204 - 支持基本类型的数组(string 、 []byte 除外,因为它们不定长) 205 - 支持定长struct的数组 206 207 208 ## 指针类型 209 210 - 支持struct指针(默认格式) 211 212 go类型 | 内存说明 |byte含义说明 213 ------------ | ----------------------------------------|-------------- 214 struct ptr | [1 byte] + [len(struct内存占用) byte] | 1byte值为0,表示指针为nil 215 216 217 - 支持struct指针(当 cstruct.OptionSliceIgnoreNil = true ) 218 219 go类型 | 内存说明 220 ------------ | ---------------------------------------- 221 struct ptr | [len(struct内存占用) byte] 222 223 224 ## 复杂类型 225 226 - 支持struct嵌套 227 - 支持基本类型的Slice 228 - 支持struct指针的Slice 229 - 支持struct的Slice 230 231 go类型 | 内存说明 232 ----- | ----------------------------- 233 slice | [2 byte] + [len(元素内存占用) byte] 234 235 ## 基准测试 236 237 ![图](assets/1.jpg) 238 239 测试环境:`阿里云ECS服务器,配置: 1 vCPU 2 GB (I/O优化) ecs.t5-lc1m2.small 1Mbps` 240 241 基准测试代码:[cstrucgo_test.go](benchmarks/cstrucgo_test.go) 242 243 244 ## 参考项目 245 246 - <https://github.com/golang/protobuf> 247 - <https://github.com/gogo/protobuf>