简体   繁体   English

如何在 cgo function 中操作 C 字符数组?

[英]How to manipulate a C character array inside a cgo function?

I have a C function, that is calling a go-Function with an char array parameter.我有一个 C function,它正在调用一个带有 char 数组参数的 go-Function。 The go-Function has to modify the content of the parameter. go-Function 必须修改参数的内容。 How to accomplish this?如何做到这一点?

void cFunction() {
 char buffer[9] = "aaabbbccc"; // 9 is in this case correct, it is not a null-terminated-string
 goFunction(buffer);
 // buffer shall be modified
}
func goFunction(cBuffer *C.char) {
  // how to modify 3-5?
  //strncpy(cBuffer+3, "XXX")
}

EDIT: to be more precise.编辑:更准确地说。 I have to implement a callbackfunction, that accepts an outparameter, which I have to manipulate.我必须实现一个回调函数,它接受一个外参数,我必须对其进行操作。

  void callback(char outbuffer[9]) {
    goFunction(outbuffer);
  }

as I understand Franks answer, I should do something like据我了解弗兰克斯的回答,我应该做类似的事情

  allocate new go buffer
  convert C buffer to go buffer
  manipulate go buffer
  allocate new C buffer
  convert go buffer to C buffer
  memcpy C buffer into outbuffer

That is too much allocation and conversion for my taste这对我的口味来说太多的分配和转换

See the documentation for Turning C arrays into Go slices to get a indexable go slice containing the C data. See the documentation for Turning C arrays into Go slices to get a indexable go slice containing the C data.

Because you are modifying the C buffer data in place, using the Go slice as a proxy, you can simply pass the same buffer to the callback.因为您正在修改 C 缓冲区数据,使用 Go 切片作为代理,您可以简单地将相同的缓冲区传递给回调。 Note that using append may allocate a new Go array for your slice, so you need to avoid it and make sure you have sufficient space available in the buffer beforehand.请注意,使用append可能会为您的切片分配一个新的 Go 数组,因此您需要避免它并确保事先在缓冲区中有足够的可用空间。

func goFunction(cBuffer *C.char, length int) {
    slice := (*[1 << 28]C.char)(unsafe.Pointer(cBuffer))[:length:length]
    // slice can now be modified using Go syntax, without pointer arithmetic
    
    C.callback(cBuffer)
}

It is not recommanded to modify C struct in Go, or Go struct in C.不建议修改 Go 中的 C 结构,或 Z01250F83740143D4 中的 Go 结构。 Convert it at the interface, Ref1 .在接口Ref1处转换它。

A few special functions convert between Go and C types by making copies of the data.一些特殊功能通过复制数据在 Go 和 C 类型之间进行转换。 In pseudo-Go definitions在伪 Go 定义中

More, give you a way to convert string with zero copy, Ref2 .更多,给你一种用零拷贝Ref2转换字符串的方法。

func char2Slice(data unsafe.Pointer, len C.int) []byte {
    var value []byte
    sH := (*reflect.SliceHeader)(unsafe.Pointer(&value))
    sH.Cap, sH.Len, sH.Data = int(len), int(len), uintptr(data)
    return value
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM