Convert Go []byte to a C *char

≯℡__Kan透↙ 提交于 2019-12-03 03:49:10

If you want to use your first approach, you need to create the slice outside the function call arguments, and avoid the temporarily allocated slice header or the outer structure in the arguments, so the cgo checks don't see it as a pointer stored in Go.

b := buf.Bytes()
rc := C.the_function(unsafe.Pointer(&b[0]), C.int(buf.Len()))

The C.CString method will be safer, in that the data is copied into a C buffer, so there is no pointer to Go memory, and there's no chance the slice behind the bytes.Buffer will be modified or go out of scope. You will want to convert the whole string, not just the first byte. This methods does need to allocate and copy twice, however if the amount of data is small it's probably not a concern compared to the overhead of the cgo call itself.

str := buf.String()
p := unsafe.Pointer(C.CString(str))
defer C.free(p)
rc = C.the_function(p, C.int(len(str)))

If the 2 copies of the data aren't acceptable in that solution, there is a third option where you malloc the C buffer yourself, and make a single copy into that buffer:

p := C.malloc(C.size_t(len(b)))
defer C.free(p)

// copy the data into the buffer, by converting it to a Go array
cBuf := (*[1 << 30]byte)(p)
copy(cBuf[:], b)
rc = C.the_function(p, C.int(buf.Len()))

But with both of those latter options, don't forget to free the malloc'ed pointer.

alex

Your program crashes because rules of passing pointers into C changed in go1.6 (see https://tip.golang.org/doc/go1.6#cgo for details).

I don't know why your program crashes, so I have created Go issue https://github.com/golang/go/issues/14546.

But regardless of answer on the issue, I wouldn't use internal bits of bytes.Buffer (as you do) to pass into cgo directly. The bytes.Buffer implementation can change in the future, and you program will start breaking mysteriously. I would just copy data you need into whatever structure is appropriate and use that to pass into cgo.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!