I am using some C library form Go, using cgo to handle the conversion.
I have a C header file that looks like:
#include <stdlib.h>
typedef struct {
k uint64_t;
} params;
This structure is used from Go with code like:
package test
/*
#cgo CFLAGS: -g -Wall
#cgo LDFLAGS: -L. -lmylib -lm -ldl
#include "mylib.h"
*/
import "C"
func NewParams(k uint64) Paramets {
return Params{
k: C.ulonglong(k),
}
}
The code compiles fine on OS X with Apple clang version 12.0.0, but fails on Linux with clang version 7.1.0, yielding the following error:
cannot use _Ctype_ulonglong(k) (type _Ctype_ulonglong) as type _Ctype_ulong in field value
If I change the call to C.ulonglong
to C.ulong
, it works fine on linux but then fails on OS X.
How can I ensure the same code works on both platform?
Using go build -work
I was able to confirm the issue stems from differences in mapping:
unit64_t
gets mapped to a C.ulong
C.ulonglong
Note that both C.ulong
and C.ulonglong
gets mapped to a go uint64
but using the Go type directly and removing the C.xxx(k)
conversion fails.
Solution is to use C.uint64_t(k)
which makes it explicit the size of the type we are talking about. This is just fine because the C type is uin64_t
anyways.