I'm working with a c structure which happens to be pack to two byte alignments in the library that cgo is linking against. I noticed unsafe.Sizeof doesn't respect the packing, and will return the unpacked size of the structure. As a workaround i've created mini helper C functions to return the size of a given type (
http://play.golang.org/p/o3fSS5mUcp). I'm curious if there is a better way to do this.
As an example gssapi on mac use #parama pack(2), all other platforms are not packed, of course.
typedef struct gss_OID_desc_struct {
OM_uint32 length;
void *elements;
} gss_OID_desc, *gss_OID; // 16 bytes from Go's unsafe.Sizeof(C.gss_OID_desc{}), but 12 bytes in c's sizeof(gss_OID_desc)
typedef struct gss_OID_set_desc_struct {
size_t count;
gss_OID elements;
} gss_OID_set_desc, *gss_OID_set;
The set's elements cannot be converted to a slice through reflection/unsafe.Pointer, because the slice header creation will think the gss_OID_desc type has a size of 16 bytes not 12, causing memory errors when used. So to move through the element list i need to do the following:
/*
...
int size_of_gss_OIB_set_desc() {
return sizeof(gss_OID_desc);
}
*/
import "C"
...
var ptr unsafe.Pointer = unsafe.Pointer(set.elements)
for idx = 0; idx < set.count; idx++ {
elem = (C.gss_OID)(ptr)
// stuff ...
if idx < set.count {
ptr = unsafe.Pointer(uintptr(ptr) + uintptr(C.size_of_gss_OIB_set_desc()))
}
}
Any suggestions?
Cheers,
jasdel