go c 通过内存原始二进制内容直接传递结构体
传统数据传输通常通过半结构化数据(json/yaml/xml…)来交换信息。但是go 支持 二进制数据层面支持c 结构体。带来的好处就是相较于半结构化数据类型来说更快(在go中,解析和生成json/yaml/xml…到结构体都会经过一层反射到结构体,数据单向流通会是1层反射,如果数据双向即生成又要解析那么就会用上2层反射).
而使用内存直接交换(在不涉及指针(由于指针只是一个记录硬件地址的一个地址,也叫做虚拟指针。只在单个进程中有效,到其它进程中只是一串毫无用处的占8位字节的数字uint64),字符串类型的情况下是非常快的).
此处直接书接上文[go 内存二进制数据操作]继续。类型定义不清楚的可以看那边文章.本文内存二进制数据采取直接写入和从文件中读出。若你想使用共享内存来代替,可参考我的文章[golang 操作共享内存]
type SharePointer[T any] struct {*Pointer[T]
}func (s *SharePointer[T]) Dump(w io.Writer) {_, err := w.Write(s.Bytes())if err != nil {panic("write to disk failed " + err.Error())}
}
//一个计数类型,占用8位字节
//在操作原始内存上推荐使用明确大小的类型.如使用int32 代替int,因为int随着系统的变换对应的位数在变动
type Count struct {A uint32B uint16C uint16
}func NewSharePointer[T any]() *SharePointer[T] {return &SharePointer[T]{Pointer: NewPointer[T]()}
}
func main() {ptr := NewSharePointer[Count]()f, err := os.OpenFile("test.shm", os.O_CREATE|os.O_WRONLY, 0644)if err != nil {panic("open test.shm failed " + err.Error())}//修改一下数据ptr.Pointer.T.A = 23ptr.Pointer.T.B = 13ptr.Pointer.T.C = 23defer f.Close()ptr.Dump(f) //写入硬盘//从硬盘中读取fe, err := os.OpenFile("test.shm", os.O_RDONLY, 0640)if err != nil {panic("read test.shm failed " + err.Error())}defer fe.Close()_, err = fe.Read(ptr.Bytes())if err != nil {panic("read test.shm failed " + err.Error())}fmt.Println(*ptr.T)
}
c 操作
c 操作很简单,直接将结果体指针写入文件,读取也是一样
#include <stdint.h>
#include <unistd.h>
struct __count{uint32_t a;uint16_t b;uint16_t c;
};
int main(){struct __count count;//....write(fd,&count,sizeof(count));read(fd,&count,sizeof(count));//....
}