cstruct

package
v1.3.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 19, 2023 License: Apache-2.0, MIT Imports: 6 Imported by: 0

README

cstruct-go

a fast c-style struct packer & unpacker for golang

特性

  • Go struct 与 C struct 一一对应,内存分布一致。
  • 快速。
  • 方便,只需要定义 struct 即可。

例子1

  1. 定义举例

    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
    }
    
  2. 使用举例

    a := &mystruct1{}
    // ...(初始化a 代码略)...
    
    // 序列化代码如下,返回 []byte类型数据
    buf_l, _ := cstruct.Marshal(a)
    
    // 反序列化代码如下
    b := &mystruct1{}
    if err := cstruct.Unmarshal(buf_l, b); err != nil {
        fmt.Println(err)
        return
    }
    

详细例子可以参考:

例子2

演示 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("cstruct data len = ", len(data))
      fmt.Println("cstruct data is:")
      for i := 0; i < len(data); i++ {
        fmt.Printf("%d ", data[i])
      }
    }
    
  • 以上控制台输出

    D:\golang\src\github.com\fananchong\ccstruct-go\example>main.exe
    len(b) = 76
    cstruct data len =  47
    cstruct 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\ccstruct-go\example>main_cpp.exe
    len(b) = 47
    cstruct data len = 47
    cstruct 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

参考项目

Documentation

Overview

package proto

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNil = errors.New("cstruct: Pack called with nil")
)
View Source
var OptionSliceIgnoreNil = false

slice 元素类型为指针时,是否忽略nil

Functions

func Pack

func Pack(obj IStruct) ([]byte, error)

func Unpack

func Unpack(buf []byte, obj IStruct) error

Types

type Buffer

type Buffer struct {
	// contains filtered or unexported fields
}

func NewBuffer

func NewBuffer(e []byte) *Buffer

func (*Buffer) Marshal

func (p *Buffer) Marshal(obj IStruct) error

func (*Buffer) Reset

func (p *Buffer) Reset()

func (*Buffer) Unmarshal

func (p *Buffer) Unmarshal(obj IStruct) error

type IStruct

type IStruct interface {
}

type Properties

type Properties struct {
	Name string
	// contains filtered or unexported fields
}

type StructProperties

type StructProperties struct {
	Prop []*Properties
	// contains filtered or unexported fields
}

func GetProperties

func GetProperties(t reflect.Type) *StructProperties

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL