2016-09-06 71 views
2

鑑於我有一個C結構如下。我能夠使用不安全的指針讀取數據聯合值,但無法確定如何設置聯合數值數據?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代表聯合作爲一個字節數組,最長的類型設置字節數組的長度。

+1

就像你可以用'unsafe.Pointer'讀取值一樣,你也應該能夠寫出它們。 – fuz

回答

0

看起來cgo將聯合值轉換爲字節數組。因此,您可以使用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 

這是不安全非便攜雖然,所以如果有人有更好的方法,我很樂意學習它。

+0

這是一個糟糕的主意,因爲你無緣無故地引入了依賴性。 – fuz

+0

@FUZxxl正如我寫的,我想知道更好的方法來做到這一點。如果你有一個,爲什麼不寫一個答案? –

+1

沒有理由需要使用編碼/二進制來在這裏寫入值。你有價值和地址,只需分配它。 – JimB