前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Golang下通过syscall调用win32的api

Golang下通过syscall调用win32的api

作者头像
李海彬
发布2018-03-21 11:19:40
2.2K0
发布2018-03-21 11:19:40
举报
文章被收录于专栏:Golang语言社区Golang语言社区

源于golang群中再次提到windows下获取磁盘空间的方法

由于golang的api并非完全跨平台, golang本身并没有直接提供windows下的方式

syscall.Syscall系列方法

当前共5个方法

代码语言:javascript
复制
syscall.Syscallsyscall.Syscall6syscall.Syscall9syscall.Syscall12syscall.Syscall15

分别对应 3个/6个/9个/12个/15个参数或以下的调用

参数都形如

代码语言:javascript
复制
syscall.Syscall(trap, nargs, a1, a2, a3)

第二个参数, nargs 即参数的个数,一旦传错, 轻则调用失败,重者直接APPCARSH

多余的参数, 用0代替

调用示例

获取磁盘空间

代码语言:javascript
复制
//首先,准备输入参数, GetDiskFreeSpaceEx需要4个参数, 可查MSDNdir := "C:"lpFreeBytesAvailable := int64(0) //注意类型需要跟API的类型相符lpTotalNumberOfBytes := int64(0)
lpTotalNumberOfFreeBytes := int64(0)//获取方法的引用kernel32, err := syscall.LoadLibrary("Kernel32.dll") // 严格来说需要加上 defer syscall.FreeLibrary(kernel32)GetDiskFreeSpaceEx, err := syscall.GetProcAddress(syscall.Handle(kernel32), "GetDiskFreeSpaceExW")//执行之. 因为有4个参数,故取Syscall6才能放得下. 最后2个参数,自然就是0了r, _, errno := syscall.Syscall6(uintptr(GetDiskFreeSpaceEx), 4,
            uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("C:"))),
            uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
            uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)),
            uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)), 0, 0)            // 注意, errno并非error接口的, 不可能是nil// 而且,根据MSDN的说明,返回值为0就fail, 不为0就是成功if r != 0 {
    log.Printf("Free %dmb", lpTotalNumberOfFreeBytes/1024/1024)
}

简单点的方式? 用syscall.Call

跟Syscall系列一样, Call方法最多15个参数. 这里用来Must开头的方法, 如不存在,会panic.

代码语言:javascript
复制
    h := syscall.MustLoadDLL("kernel32.dll")
    c := h.MustFindProc("GetDiskFreeSpaceExW")
    lpFreeBytesAvailable := int64(0)
    lpTotalNumberOfBytes := int64(0)
    lpTotalNumberOfFreeBytes := int64(0)
    r2, _, err := c.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("F:"))),
        uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
        uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)),
        uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)))    if r2 != 0 {
        log.Println(r2, err, lpFreeBytesAvailable/1024/1024)
    }

小提示

传struct不是个好想法, 不同语言之间的差异不好磨合

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-05-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • syscall.Syscall系列方法
  • 调用示例
  • 简单点的方式? 用syscall.Call
  • 小提示
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档