我正试图从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
。有谁可以帮助我?
答案 0 :(得分:6)
size
是一个输入输出参数。进行调用时,必须将其设置为缓冲区的大小(arr
)。它的类型也是PULONG
,因此在Go中使用uint32
。 Windows 类型是指向PULONG
(范围为0..4294967295
)的指针。请参阅ULONG
。
同样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
指定的大小(您通过了{{1作为0
)。
工作代码(注意由于unicode而除以2,对于用于大小计算的终止size
字节/字符,减去1:
'\0'
在这种情况下,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