admin管理员组文章数量:1391850
I have a file written in C with the format "header.h", and I want to read it using CGO to automatically retrieve the field names defined in header.h.
Here is a shortened example where I include the contents of header.h directly in t.go.
t.go
package main
// #pragma pack(push, 1)
// typedef struct {
// char tag;
// short id;
// } header;
// #pragma pack(pop)
import "C"
import ( "fmt"; "unsafe")
func main() {
value := [8]byte{1,2,3,4,5,6,7,8}
goHeader := (*C.header)(unsafe.Pointer(&value))
fmt.Printf("sizeof=%d tag=%d id=%d %+v\n",
C.sizeof_header,
goHeader.tag,
3, // goHeader.id // if I use this it cause id not defined
goHeader)
}
result compiled by go 1.24.1
sizeof=3 tag=1 id=3 &{tag:1 _:[2 3]}
expect result
sizeof=3 tag=1 id=770 &{tag:1 id:770}
As I know the reason of this behavior is the mismatch alignment between C & Go, but what's better method instead of manual rewrite every field name?
I have a file written in C with the format "header.h", and I want to read it using CGO to automatically retrieve the field names defined in header.h.
Here is a shortened example where I include the contents of header.h directly in t.go.
t.go
package main
// #pragma pack(push, 1)
// typedef struct {
// char tag;
// short id;
// } header;
// #pragma pack(pop)
import "C"
import ( "fmt"; "unsafe")
func main() {
value := [8]byte{1,2,3,4,5,6,7,8}
goHeader := (*C.header)(unsafe.Pointer(&value))
fmt.Printf("sizeof=%d tag=%d id=%d %+v\n",
C.sizeof_header,
goHeader.tag,
3, // goHeader.id // if I use this it cause id not defined
goHeader)
}
result compiled by go 1.24.1
sizeof=3 tag=1 id=3 &{tag:1 _:[2 3]}
expect result
sizeof=3 tag=1 id=770 &{tag:1 id:770}
As I know the reason of this behavior is the mismatch alignment between C & Go, but what's better method instead of manual rewrite every field name?
Share Improve this question asked Mar 12 at 9:08 Daniel YC LinDaniel YC Lin 16.1k18 gold badges69 silver badges104 bronze badges 1 |1 Answer
Reset to default 2According to the Go Wiki: cgo:
Common Pitfalls: Struct Alignment Issues
As Go doesn’t support packed struct (e.g., structs where maximum alignment is 1 byte), you can’t use packed C struct in Go. Even if your program passes compilation, it won’t do what you want. To use it, you have to read/write the struct as byte array/slice.
So, either align the fields so that Go can deal with it:
package main
// typedef struct {
// char tag;
// short id;
// } header;
import "C"
import (
"fmt"
"unsafe"
)
func main() {
value := [8]byte{1, 0, 2, 3}
goHeader := (*C.header)(unsafe.Pointer(&value))
fmt.Printf("sizeof=%d tag=%d id=%d %+v\n",
C.sizeof_header,
goHeader.tag,
goHeader.id,
goHeader)
}
Gives sizeof=4 tag=1 id=770 &{tag:1 id:770}, or use the byte array.
版权声明:本文标题:cgo - How to process mismatch C & Go structure issue when Go process C written file format? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744762806a2623852.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
encoding/binary
to serialize those values to bytes. Another approach is to have "mirror" Gostuct
types and methods/functions which would encode values of those types to bytes.cgo
does not support "packing" control, so there's no other portable way of doing what you're after. – kostix Commented Mar 12 at 14:10