我一直在尝试使用netapi32.dll,但是我的结果好坏参半。
下列工作按预期进行
type SERVER_INFO_101 struct {
PlatformID uint32
Name *uint16
VersionMajor uint32
VersionMinor uint32
Type uint32
Comment *uint16
}
func NetServerGetInfo() {
info := &SERVER_INFO_101{}
ret, _, err := procNetServerGetInfo.Call(0, 101, uintptr(unsafe.Pointer(&info)))
if ret != 0 {
log.Fatal(err)
}
spew.Dump(info)
}然而,我不知道为什么信息必须有&在unsafe.Pointer中也有。
以下内容不起作用,我似乎也找不出原因。没有错误代码被抛出。结构或变量都不会被填写。
type SESSION_INFO_10 struct {
Cname *uint16
Username *uint16
Time uint32
IdleTime uint32
}
func NetSessionEnum() {
info := &SESSION_INFO_10{}
var prefmaxlen int32 = -1
var entriesread uint32
var totalentries uint32
var resumehandle uint32
x, y, z := procNetSessionEnum.Call(0, 0, 0, 10, uintptr(unsafe.Pointer(info)), uintptr(prefmaxlen), uintptr(unsafe.Pointer(&entriesread)), uintptr(unsafe.Pointer(&totalentries)), uintptr(unsafe.Pointer(&resumehandle)))
fmt.Println(x, y, z)
fmt.Println(entriesread, totalentries)
spew.Dump(info)
}发布于 2016-03-09 14:36:10
…因为你不应该传递一个指向你的内存块的指针--引用手册
此缓冲区由系统分配,必须使用NetApiBufferFree函数释放。
该指针的类型具有误导性,但您应该将指针传递到那里的指针,如下所示:
func NetSessionEnum() {
var pinfo *SESSION_INFO_10
var prefmaxlen int32 = -1
var entriesread uint32
var totalentries uint32
var resumehandle uint32
x, y, z := procNetSessionEnum.Call(0, 0, 0, 10,
uintptr(unsafe.Pointer(&pinfo)), uintptr(prefmaxlen),
uintptr(unsafe.Pointer(&entriesread)),
uintptr(unsafe.Pointer(&totalentries)),
uintptr(unsafe.Pointer(&resumehandle)))
fmt.Println(x, y, z)
fmt.Println(entriesread, totalentries)
spew.Dump(info)
}
// Now use `*pinfo.Cname` etc
// Don't forget to later call `NetApiBufferFree()` on that pointer.这里发生了什么:
pinfo是指向SESSION_INFO_10类型值的指针。NetSessionEnum()。pinfo变量的地址,缓冲区的地址最终被写入变量pinfo。pinfo中的地址来访问NetSessionEnum()分配的内存。这被称为“双重间接”,并在相当多的地方使用Win32 API。请阅读手册页并学习其中包含的代码示例。
更新:原来的代码有更多的问题,所以我花时间提供了完整的解决方案--这里是要点(在Windows 32位、R2 64位和Windows8.1 64位上进行了Go 1.6 amd64和i386测试)。
https://stackoverflow.com/questions/35885460
复制相似问题