[英]CGO: Convert between LPCWSTR and string
我正在為一個使用LPCWSTR
的所有字符串類型的庫編寫 CGO 綁定。 如何從C.LPCWSTR
轉換為string
,反之亦然?
您應該能夠將LPCWSTR
“投射”為[]uint16
,並使用utf16
包來解碼字符
// take a C.wstr pointer, and convert it to a go slice
// `sz` is the length of the LPCWSTR
wstr := (*[1 << 30-1]uint16)(unsafe.Pointer(C.wstr))[:sz:sz]
runes := utf16.Decode(wstr)
goString := string(runes)
你一般不希望被路過的圍棋指針到你的C代碼,所以從字符串轉換為LPCWSTR時,你會想在頁頭C.解決辦法的內存從一個圍棋字符串轉換s
可能看起來像:
func Encode(s string) C.LPCWSTR {
wstr := utf16.Encode([]rune(s))
p := C.calloc(C.size_t(len(wstr)+1), C.sizeof_uint16_t)
pp := (*[1 << 30]uint16)(p)
copy(pp[:], wstr)
return (C.LPCWSTR)(p)
}
可能還有一些 MFC 宏可以幫助轉換為 cstrings 和從 cstrings 轉換,您可以利用 C 中的簡單包裝函數來利用這些宏。這樣,您只需使用內置的C.CString
和C.GoString
就可以輕松地將數據復制進和出功能。
如果您確定輸入不包含空字節,您可以自己進行編碼:
import (
// #include <windows.h>
"C"
"unicode/utf16"
"unsafe"
)
func PtrFromString(s string) C.LPCWSTR {
r := []rune(s + "\x00")
e := utf16.Encode(r)
p := unsafe.Pointer(&e[0])
return (C.LPCWSTR)(p)
}
作為在 C 中分配內存的另一種方法,可以調用 syscall.UTF16PtrFromString:
func Encode(s string) C.LPCWSTR {
ptr, _ := syscall.UTF16PtrFromString(s)
return C.LPCWSTR(unsafe.Pointer(ptr))
}
這假設您嘗試調用的 API(假設是 win32 API,因為您使用的是 LPCWSTR)沒有制作任何字符串指針的副本。 如果確實如此,如果 GoLang 的代碼范圍合適,則不分配 C 內存應該是安全的。
例如,下面的代碼行應該沒問題:
func DoSomeWindowsStuff(arg string) {
CallWin32API(Encode(arg))
}
這里為字符串分配的內存應該一直存在,直到 CallWin32API() 返回。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.