我有一个 c 联合,将我的数据存储为值结构的一部分
union data_union {
char *string_val;
int8_t int8_val;
int64_t int64_val;
// so on
};
typedef enum {
MY_STRING,
MY_INT8,
MY_INT64,
// so on
} data_type;
struct value_struct {
data_type type;
data_union data;
}
如果我想从 c 读取 int8 值到 go 我使用
int8_val := *(*C.int8_t)(unsafe.Pointer(&(cValue.data[0])))
goInt := int64(int8_val)
对于 int64 值也类似
int64_val := *(*C.int64_t)(unsafe.Pointer(&(cValue.data[0])))
goInt := int64(int64_val)
如何读取 char * null 结尾的字符串?
我正在执行以下操作,但我得到了垃圾值
string_val := C.GoString((*C.char)(unsafe.Pointer(&(cValue.data[0]))))
我尝试过投射为单个角色,但无济于事
var cString []byte
ptr := unsafe.Pointer(&(cValue.data[0]))
for {
char := *(*C.char)(ptr)
if char == 0 {
break
}
cString = append(cString, byte(char))
ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(char))
}
goString := string(cString)
我尝试过转换为 unsafe.Slice,但老实说我不明白,而且它不起作用
cStringPtr := (*byte)(unsafe.Pointer(&(cValue.data[0])))
cString := unsafe.Slice(cStringPtr, 0)
// Convert the byte slice to a Go string
goString := string(cString)
经过一番修改,我意识到我可以从 C 方面的 C 函数返回
char *
char *get_value_str(struct value_struct *value) {
return value->data.string_val;
}
然后去端的转换就很简单了
goString := C.GoString(C.get_value_str(cValue))
仍然在寻找更好的方法,因为我的联合中有很多条目,并且我不想在项目中用包装器到包装器污染我的 go 代码,其中整个项目首先是 c api 的包装器地点。