如何从cgo中的c联合读取char *字符串?

问题描述 投票:0回答:1

我有一个 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 go cgo
1个回答
0
投票

经过一番修改,我意识到我可以从 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 的包装器地点。

© www.soinside.com 2019 - 2024. All rights reserved.