What's the equivalent of mempcy() for *C.char?
I have a function that will be called from C using -buildmode=c-shared:
myGoStr := "blabla"
//export GetString
func GetString(text *C.char) {
memcpy(text, myGoStr)
}
- memory is allocated in C
- string is golang type
How can I copy the Go string to the C allocated memory behind *C.char?
I'm well aware of all the C.String functions (https://pkg.go.dev/cmd/cgo#hdr-Go_references_to_C) but I don't want Go to allocate the memory, I want to work directly with a C pointer given by the C application.
The only way I found is:
cStr := C.CString(text)
C.strcpy(text, cStr)
C.free(unsafe.Pointer(cStr))
but it's too overkill since it involves 2 copies (C.CString and C.strcpy)
There are multiple ways to achieve what you want but the thing is, either way will be unsafe — in one way or another. The reason for this is that
memcpyis already unsafe (in the Go's frame of thinking) because its third argument — the number of bytes to copy — is not somehow obtained from the rest of that function's arguments (what the Go'scopydoes).So yes, you can avoid the usual Go's
unsafedance to construct a slice out of your*C.charto pass tocopyand have that warm cozy feeling of being safe, but then another solution — such as just callingmemcpydirectly — will anyway rely on the said*C.charto point to a memory block with enough free space to contain at least as much bytes there is in the Go's source string, plus one, and nothing guarantees that.I mean, if you want to go this way, you can just do that:
But as there's no safeness anyway, I would argue that the analogous
is just clearer and and just as unsafe.
To reiterate in other words, you cannot do memory operations with the C side from your Go side and still claim your Go side is safe.