![](/img/trans.png)
[英]How can I determine the windows libraries required for a specific win32 api call?
[英]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.