dougou6727 2018-08-17 08:11
浏览 189
已采纳

指针字符串切片(* [] string)的Cgo指针传递规则?

Can I pass *[]string to C from Go and then append to the string slice, or is it violating the pointer passing spec?

Go code may pass a Go pointer to C, provided the Go memory to which it points does not contain any Go pointers.

Example code:

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))
}
  • 写回答

2条回答 默认 最新

  • dtf579777 2018-08-23 18:40
    关注

    Passing a *[]string to C is not allowed because the memory pointed to contains strings and strings contain pointers. As the cgo docs say (emphasis mine)

    Note that values of some Go types, other than the type's zero value, always include Go pointers. This is true of string, slice, interface, channel, map, and function types.

    One way to overcome this is to refer to the []string more indirectly so only Go code actually knows its address. For example:

    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))
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 Python爬取指定微博话题下的内容,保存为txt
  • ¥15 vue2登录调用后端接口如何实现
  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?