我可以将*[]string从Go传递给C,然后将append传递给字符串片,还是它违反了指针传递规范?
Go代码可以传递一个Go指针到C,条件是它所指向的Go内存不包含任何Go指针。
示例代码:
package main
/*
extern void go_callback(void*, char*);
static inline void callback(void* stringSliceGoPointer) {
go_callback(stringSliceGoPointer, "foobar");
}
*/
import "C"
import (
"fmt"
"unsafe"
)
func main() {
a := make([]string, 0)
C.callback(unsafe.Pointer(&a))
fmt.Println(a[0]) // outputs foobar
}
//export go_callback
func go_callback(stringSliceGoPointer unsafe.Pointer, msg *C.char) {
slice := (*[]string)(stringSliceGoPointer)
*slice = append(*slice, C.GoString(msg))
}发布于 2018-08-23 18:40:27
不允许将*[]string传递给C,因为指向的内存包含字符串,字符串包含指针。正如cgo文档所说(强调我的)
注意,一些Go类型的值是,除了该类型的零值之外,总是包含Go指针。对于字符串、片、接口、通道、映射和函数类型,这是正确的。
克服这一问题的一种方法是更间接地引用[]string,因此只有Go代码才知道其地址。例如:
package main
/*
extern void go_callback(int, char*);
static inline void callback(int stringSliceRef) {
go_callback(stringSliceRef, "foobar");
}
*/
import "C"
import (
"fmt"
)
// If you need to use these values concurrently,
// you'll need more code to protect this.
var stringSlices = make([][]string, 10)
func main() {
C.callback(0)
fmt.Println(stringSlices[0][0]) // outputs foobar
}
//export go_callback
func go_callback(ref C.int, msg *C.char) {
i := int(ref)
stringSlices[i] = append(stringSlices[i], C.GoString(msg))
}发布于 2018-08-21 06:47:01
不,这不可能。
有关go数据类型的进一步说明,请参阅这。
基本上,Go中的字符串类型如下所示。
str := "hello"这是作为,
str: 0xad234e3b:
┌──────────┬─┐ ┌───┬───┬───┬───┬───┐
|0xad234e3b|5| ┌──>|104|101|108|108|111| -->[5]byte
└────┬─────┴─┘ | └───┴───┴───┴───┴───┘
└──────────┘考虑一小片:
arr := string{"hi!","hello"}此外,切片数据类型包含指针、长度、容量。
arr: 0xd2b564c7: 0xad234e40:
┌──────────┬─┬─┐ ┌──────────┬─┐ ┌───┬───┬──┐
|0xd2b564c7|2|2| ┌──> |0xad234e40|3|────>|104|105|33| -->[3]byte
└────┬─────┴─┴─┘ | ├──────────┼─┤ └───┴───┴──┘
└────────────┘ |0xad234e4b|5|──┐ 0xad234e4b:
└──────────┴─┘ | ┌───┬───┬───┬───┬───┐
└─>|104|101|108|108|111| -->[5]byte
└───┴───┴───┴───┴───┘其中十六进制值表示地址。
存储实际数据的是一个[x]byte数组。
x表示数据(数组)的大小。
很明显,[]string本身包含许多(x)指针,而*[]string是另一个额外的指针。
https://stackoverflow.com/questions/51891020
复制相似问题