2016-09-06 1 views
2

Étant donné que j'ai une structure C comme ci-dessous. Je suis capable de lire les valeurs d'union de données en utilisant des pointeurs dangereux, mais je suis incapable de déterminer comment je peux définir les données de valeur d'union?cgo comment régler une valeur C union

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; 

Existe-t-il un moyen de créer des méthodes auxiliaires dans C? Un exemple de réglage de string_val serait parfait? Je suis conscient que Go représente une union en tant que tableau d'octets avec le type le plus long définissant la longueur du tableau d'octets.

+1

Tout comme vous pouvez lire les valeurs avec 'unsafe.Pointer', vous devriez aussi être capable de les écrire. – fuz

Répondre

0

Il semble que cgo transforme les valeurs d'union en tableaux d'octets. En tant que tel, vous pouvez les régler en utilisant 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) 

Ce (avec une fonction print_val appropriée) imprime:

int16: 42 
string: hello world 

Ceci est dangereux et non-portable, donc si quelqu'un a une meilleure façon, je serai heureux de l'apprendre.

+0

C'est une mauvaise idée parce que vous introduisez une dépendance à l'endianisme sans aucune raison. – fuz

+0

@FUZxxl Comme je l'ai écrit, je voudrais savoir une meilleure façon de le faire. Si vous en avez un, pourquoi ne pas écrire une réponse? –

+1

Il n'y a aucune raison que vous ayez besoin d'utiliser encoding/binary pour écrire la valeur ici. Vous avez la valeur et l'adresse, juste l'assigner. – JimB