cgo如何设置C联合值

时间:2016-09-06 09:21:37

标签: c go unions cgo

鉴于我有如下的C结构。我能够使用不安全的指针读取数据联合值,但我无法弄清楚如何设置联合值数据?

 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;

有没有办法在C中没有创建辅助方法?设置string_val的一个例子是完美的吗?我知道Go表示一个union作为一个字节数组,其中最长的类型设置了字节数组的长度。

1 个答案:

答案 0 :(得分:1)

似乎cgo将union值转换为字节数组。因此,您可以使用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)

这(使用适当的print_val函数)打印:

int16: 42
string: hello world

这是不安全非便携,但如果有人有更好的方法,我很乐意学习它。