【问题标题】:cgo - How to convert string to C fixed char arraycgo - 如何将字符串转换为 C 固定字符数组
【发布时间】:2014-10-09 05:48:24
【问题描述】:

我正在尝试在我的 Go 代码中实例化一个 C 结构。 该结构是这样定义的,(在我无法修改的外部库中):

typedef struct {
    char field1[256];
} S1

在进行中,我这样做了:

func myfunc(mystr string){
    // We need to convert mystr from string to char array
    cStr := C.CString(mystr)
    defer C.free(unsafe.Pointer(cStr)

    // Should work now
    s1 := &C.S1{field1: cStr}

    // Do something with s1...
}

但它没有编译,因为:

不能在字段值中使用 cStr (type *C.char) 作为类型 [256]C.char

我试过强制 ([256]C.char)(cStr) 但它显然也不起作用。

有没有办法实现我想要做的事情?

【问题讨论】:

  • 使用类似copy(sq.fields[:], mystr)的东西。

标签: c go type-conversion cgo


【解决方案1】:

最简单的解决方案是将结构的字段定义更改为字符指针,这对于 C 中的字符串非常标准:

typedef struct {
    char *field1;
} S1

更复杂的解决方案是[1]

arr := [256]C.char{}

for i := 0; i < len(mystr) && i < 255; i++ { // leave element 256 at zero
    arr[i] = C.char(mystr[i])
}

s1 := &C.S1{field1: arr}

[1] 代码未经测试,无法在此工作站上编译。

【讨论】:

  • 不幸的是,我无法修改结构。它来自外部库。
  • 您提供的代码有效:)。非常感谢!
  • 你可以使用内置的copy()函数。
【解决方案2】:

不幸的是,在 Go 中没有任何方便的方法可以将 [size]C.char 处理为字符串(我想我看到了一个建议,可以在某个时候添加它......)

在我的代码中,我没有直接处理它,而是选择在需要时手动将字符串写入结构体

func strCopy(dest *[maxTextExtent]C.char, src []byte) {
    for i, c := range src {
        dest[i] = C.char(c)
    }
    // This is C, we need to terminate the string!
    dest[len(src)] = 0
}

而我过去的处理方式,安全性要低得多

s1 := &C.S1{
    field1: *(*[256]C.char)(unsafe.Pointer(cStr)),
}

【讨论】:

  • 嗯我想知道是否真的需要dest[len(src)],因为go中的数组/切片是0'ed。
  • @OneOfOne:您可能正在覆盖现有数组,它可能已在 C 中分配。
  • 如果src 的长度大于或等于maxTextExtent,您的代码将写入超出dest 的上限 恐慌。
  • @tomwilde:我知道,但是 Go 会在这里正确地恐慌(在 c 中你绝对想检查)
  • @David23:没问题 :),不过请检查最新的编辑。我不提倡你使用它,但你可能对直接分配它的工作方式感兴趣。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-20
  • 2015-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多