How to get sizeof struct with packed struct size in C?

906 views
Skip to first unread message

dlin

unread,
Apr 8, 2012, 11:20:17 PM4/8/12
to golan...@googlegroups.com
I try to use encoding/binary to read a binary file which is generated by C.

Assume a variable v declared with type T.

In C, the packed structure size can easy get by sizeof(T) or sizeof(v).
In Go, I could use unsafe.Sizeof(v).

But, I found the unsafe.Sizeof(v) is larger then C's sizeof(T).
I've compared the binary data which read from encoding/binary, it is correct.
I guess the extra bytes in Go is depend on Go implementation.
Is there any method in unsafe could get the C's sizeof?
I wish use this value to estimate binary file size.

dga

unread,
Apr 8, 2012, 11:56:09 PM4/8/12
to golan...@googlegroups.com
If I read you correctly, your real goal is to ask:  "What is the encoding/binary size of struct T", not "what is the Go internal representation size of struct T", right?

If you know the struct in advance and don't mind relying on code generation, I've added a quick hack to my (very work-in-progress -- beware) encoding/binary code generator:


It will output a function like:

func (t *Demostruct) BinarySize() (nbytes int, sizeKnown bool) {
        return 20, true
}

If you find it useful, let me know.  It'll help me resist the temptation to change things in incompatible ways if I know someone's actually using it.

But to answer the question you asked:  Not really, because the sizeof is _entirely_ an implementation choice when you're talking about the language-specific in-memory layout.  But hopefully, you actually meant the encoding/binary specific question, which _does_ have a single answer.

  -Dave

Hotei

unread,
Apr 9, 2012, 1:00:55 AM4/9/12
to golan...@googlegroups.com
Assuming you don't mind that the result isn't going to be portable I'd probably use a hex editor to inspect the output file from the C program and hard-code the sizes in my go reader.  If you read the binary data in as a byte slice you can easily pick apart a struct by byte position.  Tedious and not always portable, but it does work.  If it's a huge struct and _IF_  CGO is compatible that might work better.  A bit of trial and error is about the best you can hope for.  The reason JSON and friends were developed is because binary representations are so "fluid" I guess is the best word I can find.


On Sunday, April 8, 2012 11:20:17 PM UTC-4, dlin wrote:

dlin

unread,
Apr 9, 2012, 1:46:59 AM4/9/12
to golan...@googlegroups.com
Dave,

Thanks.
BinarySize is what I want.

I've simplified my sample.
In fact the struct is including many sub-struct. I don't know if your gobin-codegen workable on such case.

eg.

struct header1 {...}
struct header2 {...}
struct T { header1 h; header2 h2; uint16 f3,f4,...}

dga

unread,
Apr 13, 2012, 10:45:45 AM4/13/12
to golan...@googlegroups.com
It wasn't, but it is now - kinda.  I just pushed a change that lets the code generator inline embedded structs.  It should get the sizing right.

What it *doesn't* do right is handle embedded structs from other files, however.  So this works:

type h1 struct { foo, bar int }
type h2 struct { fiz, baz h1 }

But this doesn't:
type h2 struct { fiz, baz  foo.SomeType }

The change was kind of large and might have broken some corner cases with the codegen.

  -Dave
Reply all
Reply to author
Forward
0 new messages