不使用 CGO 将 C 字符串转换为 Go 字符串
Convert C string to Go string without CGO
我正在使用 Go Windows 系统调用库从 DLL 中的函数中获取数据。这一切都很好,但我想不出一种方法来将 LPCTSTR(指向 C 字符串的指针)转换为正确的 Go 字符串 而不使用 CGO.
我想尽可能避免使用 CGO,因为 Windows 上 CGO 代码的两个选项(交叉编译,以及 windows 上安装 gcc)仍然相当复杂。
如果你可以在没有 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
}
如果您有一个 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)
我正在使用 Go Windows 系统调用库从 DLL 中的函数中获取数据。这一切都很好,但我想不出一种方法来将 LPCTSTR(指向 C 字符串的指针)转换为正确的 Go 字符串 而不使用 CGO.
我想尽可能避免使用 CGO,因为 Windows 上 CGO 代码的两个选项(交叉编译,以及 windows 上安装 gcc)仍然相当复杂。
如果你可以在没有 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
}
如果您有一个 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)