很多同学比如我虽然很喜欢golang,但是还是需要调用很多遗留项目或者其他优秀的开源项目,这时怎么办呢?我们想到的方法是用package里的syscall结合cgo

注意此处有坑:

在我调试时显示not enough arguments in call to syscall.Syscall

[ `go run dms.go` | done: 260.3744ms ]
# command-line-arguments
.\dms.go:72: not enough arguments in call to syscall.Syscall

exit status 2

因为我参照的是http://golang.org/pkg/syscall/#Syscall ,而其默认的是Linux/Unix的syscall API doc说明,

如何看windows的golang doc呢?

通过godoc command, 调用 godoc -http=:6060
然后在浏览器打开http://localhost:6060/pkg/syscall/#Syscall,这才是windows的golang pakage api

func Syscall

func Syscall(trap, nargs, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)

Implemented in ../runtime/syscall_windows.goc.

func Syscall12

func Syscall12(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2 uintptr, err Errno)

func Syscall15

func Syscall15(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2 uintptr, err Errno)

func Syscall6

func Syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)

func Syscall9

func Syscall9(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)

例子1:

func test(){
//首先,准备输入参数, GetDiskFreeSpaceEx需要4个参数, 可查MSDN
lpFreeBytesAvailable := int64(0) //注意类型需要跟API的类型相符
lpTotalNumberOfBytes := int64(0)
lpTotalNumberOfFreeBytes := int64(0) //获取方法的引用
kernel32, _ := syscall.LoadLibrary("Kernel32.dll") // 严格来说需要加上 defer syscall.FreeLibrary(kernel32)
GetDiskFreeSpaceEx, _ := syscall.GetProcAddress(syscall.Handle(kernel32), "GetDiskFreeSpaceExW") //执行之. 因为有4个参数,故取Syscall6才能放得下. 最后2个参数,自然就是0了
r, _, _ := 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)
}
}

例子2,弹出一个简单的对话框messagebox, http://code.google.com/p/go-wiki/wiki/WindowsDLLs

package main

import(
        "fmt"
        "syscall"
        "unsafe") func abort(funcname string, err error){
        panic(fmt.Sprintf("%s failed: %v", funcname, err))}var(
        kernel32, _        = syscall.LoadLibrary("kernel32.dll")
        getModuleHandle, _ = syscall.GetProcAddress(kernel32,"GetModuleHandleW")         user32, _     = syscall.LoadLibrary("user32.dll")
        messageBox, _ = syscall.GetProcAddress(user32,"MessageBoxW"))const(
        MB_OK                =0x00000000
        MB_OKCANCEL          =0x00000001
        MB_ABORTRETRYIGNORE  =0x00000002
        MB_YESNOCANCEL       =0x00000003
        MB_YESNO             =0x00000004
        MB_RETRYCANCEL       =0x00000005
        MB_CANCELTRYCONTINUE =0x00000006
        MB_ICONHAND          =0x00000010
        MB_ICONQUESTION      =0x00000020
        MB_ICONEXCLAMATION   =0x00000030
        MB_ICONASTERISK      =0x00000040
        MB_USERICON          =0x00000080
        MB_ICONWARNING       = MB_ICONEXCLAMATION
        MB_ICONERROR         = MB_ICONHAND
        MB_ICONINFORMATION   = MB_ICONASTERISK
        MB_ICONSTOP          = MB_ICONHAND         MB_DEFBUTTON1 =0x00000000
        MB_DEFBUTTON2 =0x00000100
        MB_DEFBUTTON3 =0x00000200
        MB_DEFBUTTON4 =0x00000300) func MessageBox(caption, text string, style uintptr)(result int){
        var nargs uintptr =4
        ret, _, callErr := syscall.Syscall9(uintptr(messageBox),
                nargs,
                0,
                uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))),
                uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))),
                style,
                0,
                0,
                0,
                0,
                0)
        if callErr !=0{
                abort("Call MessageBox", callErr)
        }
        result =int(ret)
        return} func GetModuleHandle()(handle uintptr){
        var nargs uintptr =0
        if ret, _, callErr := syscall.Syscall(uintptr(getModuleHandle), nargs,0,0,0); callErr !=0{
                abort("Call GetModuleHandle", callErr)
        }else{
                handle = ret
        }
        return} func main(){
        defer syscall.FreeLibrary(kernel32)
        defer syscall.FreeLibrary(user32)         fmt.Printf("Return: %d\n",MessageBox("Done Title","This test is Done.", MB_YESNOCANCEL))} func init(){
        fmt.Print("Starting Up\n")}
http://golang.org/pkg/syscall/#Syscall 里默认的是Linux/Unix的syscall API doc说明,

Golang下通过syscall调用win32的dll(calling Windows DLLs from Go )的更多相关文章

  1. paip.java c# .net php python调用c++ c dll so windows api 总结

    paip.java c# .net  php python调用c++ c dll so windows api 总结 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来 ...

  2. Windows API方式直接调用C#的DLL,支持多音字转拼音、Gzip解压缩、公式计算(VBA、C++、VB、Delphi甚至java都可以)

    原始链接 https://www.cnblogs.com/Charltsing/p/DllExport.html 这两年,我在VBA应用方面一直有几大痛点:1.多音字转拼音:2.64位下的GZIP解压 ...

  3. 关于C#调用非托管DLL,报“内存已损坏的”坑,坑,坑

    因客户需求,与第三方对接,调用非托管DLL,之前正常对接的程序,却总是报“内存已损坏的异常”,程序进程直接死掉,折腾到这个点(2018-05-11 00:26),终于尘埃落定,直接上程序. 之前的程序 ...

  4. golang调用c++的dll库文件

    最近使用golang调用c++的dll库文件,简单了解了一下,特作此笔记:一.DLL 的编制与具体的编程语言及编译器无关 dll分com的dll和动态dll,Com组件dll:不管是何种语言写的都可以 ...

  5. C++在VS下创建、调用dll

    转自:http://www.cnblogs.com/houkai/archive/2013/06/05/3119513.html 目录 1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言 ...

  6. 在 C# 中通过 P/Invoke 调用Win32 DLL

    在 C# 中通过 P/Invoke 调用Win32 DLL 发布日期 : 1/13/2005 | 更新日期 : 1/13/2005 Jason Clark 下载本文的代码: NET0307.exe ( ...

  7. C#中可直接调用WIN32的API函数--USER32.DLL

    Win32的API函数可以直接在C#中直接调用,在做WinForm时还是很有帮助的.有时候直接调用Win32的API,可以很高效的实现想要的效果. using System; using System ...

  8. vs2010下C++调用lib或dll文件

    注: DLL:表示链接库,包含dll,lib文件: dll: 表示my.dll文件 lib: 表示my.lib文件 C++ 调用.lib的方法: 一: 隐式的加载时链接,有三种方法 1  设置工程的 ...

  9. C# 调用win32 DLL报错 System.BadImageFormatException

    C# 调用win32 DLL报错  System.BadImageFormatException 项目右键属性->项目设计器->生成->平台->把'默认设置(任何 CPU)'改 ...

随机推荐

  1. awk中split函数的用法

    time='12:34:56' echo $time | awk '{split($0,a,":" ); print a[1]}' 12 echo $time | awk '{sp ...

  2. CI 笔记2,(命令规范等)

    调试模式开启,$this->output->enable_profiler(TRUE); 保留字,不能和控制器重名,有3个,CI_Controller ,Default, index.这三 ...

  3. 你好,C++(2)1.3 C++世界版图1.4 如何学好C++

    1.3  C++世界版图 C++语言的发展过程,不仅是一个特性不断增加.内容不断丰富的过程,更是一个在应用领域中不断攻城略地的过程.在其30余年的发展过程中,C++在多个应用领域都得到了广泛的应用和发 ...

  4. 在2015中使用V12版本的ReportView控件,会导致winform窗体不能正常打开

    在2015中使用V12版本的ReportView控件,会导致winform窗体不能正常打开,使用V10版本没问题,但2015中默认使用的就是V12版本,所以需要避免使用V12版本

  5. 【转载】详细解读C#中的 .NET 弱事件模式

    你可能知道,事件处理是内存泄漏的一个常见来源,它由不再使用的对象存留产生,你也许认为它们应该已经被回收了,但不是,并有充分的理由. 在这个短文中(期望如此),我会在 .Net 框架的上下文事件处理中展 ...

  6. mysql数据类型——枚举enum(‘F’,'M')

    ENUM(“value1”,“value2”,...) 说明:枚举,列值可赋予值列表中的某个成员 允许的属性:除通用属性外无其他属性 缺省值:如果列可为NULL,则为NULL:如果列为NOTNULL, ...

  7. Asp.Net使用异步性能就提升吗

      Asp.Net异步编程 随着.Net4.5的推出,一种新的编程方式简化了异步编程,在网上时不时的也看到各种打着Asp.Net异步编程的口号,如何提高性能,如何提高吞吐率! 好多文章都说得不清楚,甚 ...

  8. Python3.X与urllib

    在Python3.X中使用urllib时,不能像Python2.X一样直接使用: import urllib response = urllib.urlopen("http://www.ba ...

  9. App的token机制

    这只是网上看来的后期可能还会修改. 理论版的描述如下: (1) 服务器接收到app发送的用户名和密码后,验证用户名和密码是否正确. 如果错误则返回错误信息. 如果验证正确,生成一个随机的不重复的tok ...

  10. bzoj2215: [Poi2011]Conspiracy

    Description Byteotia的领土被占领了,国王Byteasar正在打算组织秘密抵抗运动.国王需要选一些人来进行这场运动,而这些人被分为两部分:一部分成为同谋者活动在被占领区域,另一部分是 ...