英文:
cgo how to set a C union value
问题
给定以下的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语言将联合表示为具有最长类型的字节数组,并且该类型的长度设置为字节数组的长度。
英文:
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.
答案1
得分: 1
似乎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
这种方法是不安全和不可移植的,如果有更好的方法,我会很乐意学习。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论