打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【Go语言/golang】Golang中调用DLL示例—Win32 API
不断的会有人问:在go中可以调用dll么?如何做?

这里提供一个示例(获取当前Windows版本):

   
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package main
   import (
       "syscall"
   )
   func abort(funcname string, err error) {
       panic(funcname + " failed: " + err.Error())
   }
   func print_version(v uint32) {
       major := byte(v)
       minor := uint8(v >> 8)
       build := uint16(v >> 16)
       print("windows version ", major, ".", minor, " (Build ", build, ")\n")
   }
   func main() {
       h, err := syscall.LoadLibrary("kernel32.dll")
       if err != nil {
           abort("LoadLibrary", err)
       }
       defer syscall.FreeLibrary(h)
       proc, err := syscall.GetProcAddress(h, "GetVersion")
       if err != nil {
           abort("GetProcAddress", err)
       }
       r, _, _ := syscall.Syscall(uintptr(proc), 0, 0, 0, 0)
       print_version(uint32(r))
   }


另外,转载一篇文章《golang下通过syscall调用win32的api》,原文内容如下:

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

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

当前共5个方法

1
2
3
4
5
syscall.Syscall
syscall.Syscall6
syscall.Syscall9
syscall.Syscall12
syscall.Syscall15


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

参数都形如

1
syscall.Syscall(trap, nargs, a1, a2, a3)


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

多余的参数, 用0代替
调用示例

获取磁盘空间

  
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
//首先,准备输入参数, GetDiskFreeSpaceEx需要4个参数, 可查MSDN
  dir := "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.

01
02
03
04
05
06
07
08
09
10
11
12
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不是个好想法, 不同语言之间的差异不好磨合
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
golang弹出消息框
在Go运行时托管CLR并执行.NET程序集
分享 | Go编写loader加载shellcode免杀学习
recover.panic.defer.2021.03.03
Go Interface 源码剖析
Go中看似简单的WaitGroup源码设计,竟然暗含这么多知识?
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服