我试图调用GetUserNameEx
从secur32.dll
这样的:
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
是输入输出参数。进行呼叫时,必须将其设置为缓冲区(arr
)的大小。它的类型也是PULONG
,所以在Go中使用uint32
。WindowsPULONG
类型是指向的指针ULONG
(具有range 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.
这意味着更多的数据比什么适合入缓冲区您传递可用-或者更确切地说-您用IN-OUT参数指示的大小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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句