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>