Given I have a C structure as below. I am able to read the data union values using unsafe pointers but am unable to work out how I can set the union value data?
typedef struct val {
char *var1;
type type;
union {
char *binary_val;
char *bits_val;
bool bool_val;
double decimal64_val;
char *enum_val;
char *identityref_val;
char *instanceid_val;
int8_t int8_val;
int16_t int16_val;
int32_t int32_val;
int64_t int64_val;
char *string_val;
uint8_t uint8_val;
uint16_t uint16_val;
uint32_t uint32_val;
uint64_t uint64_val;
} data;
} val_t;
Is there a way without creating helper methods in C? An example of setting string_val would be perfect? I am aware that Go represents a union as a byte array with the longest type setting the length of the byte array.
It seems that cgo turns the union values into byte arrays. As such, you can set them using encoding/binary:
v._type = 0
binary.LittleEndian.PutUint16(v.data[:], 42)
C.print_val(v)
v._type = 1
cstr := C.CString("hello world")
defer C.free(unsafe.Pointer(cstr))
binary.LittleEndian.PutUint64(v.data[:], uint64(uintptr(unsafe.Pointer(cstr))))
C.print_val(v)
This (with an appropriate print_val function) prints:
int16: 42
string: hello world
This is unsafe and non-portable though, so if anyone has a better way, I'll be glad to learn it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With