我使用Go Windows系统调用库从DLL中的函数中获取数据。这一切都很好,但我无法找到一种方法将LPCTSTR(指向C String的指针)转换为正确的Go字符串而不使用CGO 。
我想尽可能避免使用CGO,因为Windows上的两个CGO代码选项(交叉编译,在Windows上安装gcc)仍然相当复杂。
答案 0 :(得分:3)
如果您有一个8位字符串,则可以将LPCTSTR指针转换为适当大小的[]byte
,并将其复制到新的字符串或切片。
a := (*[1 << 30-1]byte)(unsafe.Pointer(lpctstr))
size := bytes.IndexByte(a[:], 0)
// if you just want a string
// goString := string(a[:size:size])
// if you want a slice pointing to the original memory location without a copy
// goBytes := a[:size:size]
goBytes := make([]byte, size)
copy(goBytes, a)
如果LPCTSTR指向包含16位unicode字符的LPCWSTR,则可以使用utf16包进行转换。
a := (*[1 << 30-1]uint16)(unsafe.Pointer(lpctstr))
size := 0
for ; size < len(a); size++ {
if a[size] == uint16(0) {
break
}
}
runes := utf16.Decode(a[:size:size])
goString := string(runes)
答案 1 :(得分:1)
如果你可以在没有CGO的情况下获得指向cstring的指针,并且你也可以得到字符串的长度,那么也许你应该首先从cstring创建一个字节切片。
import (
"reflect"
"unsafe"
)
func ToByteSlice() []byte {
var bytes []byte
shdr := (*reflect.SliceHeader)(unsafe.Pointer(&bytes))
shdr.Cap = int(stringlen)
shdr.Len = int(stringlen)
shdr.Data = uintptr(unsafe.Pointer(cpointer))
return bytes
}