参考链接: go中使用protobuf
$ protoc --go_out=./ *.proto
protoc-gen-go: unable to determine Go import path for "test.proto"
Please specify either:
• a "go_package" option in the .proto source file, or
• a "M" argument on the command line.
See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information.
--go_out: protoc-gen-go: Plugin failed with status code 1.
指定包名的位置改成:
option go_package = "./";
重新执行
protoc --go_out=./ *.proto
即可
关于通过proto消息名,创建proto.Message对象
关于protov1 v2版本的区别,v2版本的动态特性更强
//该实现仅用于proto v1版本实现 即 github.com/golang/protobuf 库
func parseRequest(msgName protoreflect.FullName, data []byte) (proto.Message,error) {
// 获取full name对应的message ,如果不存在则返回error
msgType, err := protoregistry.GlobalTypes.FindMessageByName(msgName)
if err != nil {
return nil, err
}
//上面返回的是一个message 反射类型,需要把它new出一个 protoreflect.Message类型然后转换成protoiface.MessageV1
//此时 根据源代码显示 proto.Message实现为 type Message = protoiface.MessageV1
//即type Message 为 protoiface.MessageV1 的别名
msg := proto.MessageV1(msgType.New())
err = proto.Unmarshal(data, msg)
if err != nil {
return nil, err
}
return msg, nil
}
//该实现仅用于proto v2版本实现 即"google.golang.org/protobuf/proto"库
func parseRequest(msgName protoreflect.FullName, data []byte) (proto.Message,error) {
// 获取full name对应的message ,如果不存在则返回error
msgType, err := protoregistry.GlobalTypes.FindMessageByName(msgName)
if err != nil {
return nil, err
}
//上面返回的是一个message type 反射类型,需要把它new出一个 protoreflect.Message类型然后转换成protoreflect.ProtoMessage
//此时 根据源代码显示 proto.Message实现为 type Message = protoreflect.ProtoMessage
//即type Message 为 protoreflect.ProtoMessage的别名
msg := msgType.New().Interface()
err = proto.Unmarshal(data, msg)
if err != nil {
return nil, err
}
return msg, nil
}
set CGO_ENABLED=1
set GOOS=windows
set GOARCH=386
go build -buildmode=c-shared -ldflags "-s -w" -o "pb32.dll"
set CGO_ENABLED=1
set GOOS=windows
set GOARCH=amd64
go build -buildmode=c-shared -ldflags "-s -w" -o "pb64.dll"
import "C" 并且要单独一行,在其上方的注释中必须写上 #include ;C 的标准动态库头文件,若不导入将有几率编译失败。string 特殊外,其他int、bool,等基本类型原本怎样还是怎样;string 与返回值 string 都改成 *C.char 类型,其他基本类型不用改;C.CString 转成c字符串,C.GoString 转成go字符串 , C.free 释放内存;C.CString 此方法,就必须记得释放内存。C.CString 却不使用 C.free ,内存占用只会越来越大,最后奔溃;unsafe.Pointer(&xx变量) ,这样等于没释放;vc6 的原因,使用 defer 在即将出栈时释放,会造成调用得不到返回值;Free() 用于释放!tdm-gcc 编译器,可选择64位,依然可以编译出32位,下载地址:https://jmeubank.github.io/tdm-gcc/download/;gcc 兼容性问题建议下载 msys2 后再安装 gcc,此条为建议并不一定需要;所有资料来源于互联网 感谢各位前辈~