簡體   English   中英

Golang:如何在沒有cgo的情況下調用win32 API?

[英]Golang: how can I call win32 API without cgo?

我試圖從secur32.dll調用GetUserNameEx ,如下所示:

dll, err := syscall.LoadDLL("secur32.dll")
if err != nil {
    log.Fatal(err)
}
defer dll.Release()

GetUserNameEx, err := dll.FindProc("GetUserNameExW")
if err != nil {
    log.Fatal(err)
}
arr := make([]uint8, 256)
var size uint
GetUserNameEx.Call(3, uintptr(unsafe.Pointer(&arr[0])), uintptr(unsafe.Pointer(&size)))
fmt.Println(arr)
fmt.Println(size)

此代碼編譯良好,但GetUserNameEx.Call()將失敗。 我不知道為什么我不能得到UserName 誰能幫助我?

size是一個in-out參數。 進行調用時,必須將其設置為緩沖區的大小( arr )。 它的類型也是PULONG ,所以在Go中使用uint32 Windows PULONG類型是指向ULONG (范圍為0..4294967295 )的指針。

Call()返回3個值:

func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error)

存儲返回的lastErr並打印出來。 你會這樣做,你會發現錯誤:

_, _, lastErr := GetUserNameEx.Call(
    3, uintptr(unsafe.Pointer(&arr[0])), uintptr(unsafe.Pointer(&size)))

fmt.Println(lastErr)

打印:

More data is available.

這意味着有更多的數據可用於您傳遞的緩沖區 - 或者更確切地說 - 是您使用輸入輸出參數size指示的size (您將0作為size )。

工作代碼(注意由於unicode而除以2,對於用於大小計算的終止'\\0'字節/字符減去1):

arr := make([]uint8, 256)
var size uint32 = uint32(len(arr)) / 2 - 1
_, _, lastErr := GetUserNameEx.Call(
    3, uintptr(unsafe.Pointer(&arr[0])), uintptr(unsafe.Pointer(&size)))

fmt.Println(lastErr)
fmt.Println(string(arr))
fmt.Println(arr)
fmt.Println(size)

在這種情況下, lastErr將是:

The operation completed successfully.

要正確處理錯誤:

返回的錯誤是總是不nil ,從結果構建GetLastError 在查詢錯誤之前,調用者必須檢查主要返回值以確定是否發生了錯誤(根據被調用的特定函數的語義)。 該錯誤將保證包含syscall.Errno

例:

r1, _, lastErr := GetUserNameEx.Call(
    3, uintptr(unsafe.Pointer(&arr[0])), uintptr(unsafe.Pointer(&size)))

if r1 == 0 {
    fmt.Println("ERROR:", lastErr.Error())
    return
}
// No error, proceed to print/use arr

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM