• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Golang如何调用windows下的dll动态库中的函数

    使用syscall调用

    package main
    import (
        "fmt"
        "syscall"
        "time"
        "unsafe"
    )
    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 abort(funcname string, err syscall.Errno) {
        panic(funcname + " failed: " + err.Error())
    }
    var (
        //    kernel32, _        = syscall.LoadLibrary("kernel32.dll")
        //    getModuleHandle, _ = syscall.GetProcAddress(kernel32, "GetModuleHandleW")
        user32, _     = syscall.LoadLibrary("user32.dll")
        messageBox, _ = syscall.GetProcAddress(user32, "MessageBoxW")
    )
    func IntPtr(n int) uintptr {
        return uintptr(n)
    }
    func StrPtr(s string) uintptr {
        return uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s)))
    }
    func MessageBox(caption, text string, style uintptr) (result int) {
        ret, _, callErr := syscall.Syscall9(messageBox,
            4,
            0,
            StrPtr(text),
            StrPtr(caption),
            style,
            0, 0, 0, 0, 0)
        if callErr != 0 {
            abort("Call MessageBox", callErr)
        }
        result = int(ret)
        return
    }
    //func GetModuleHandle() (handle uintptr) {
    //    if ret, _, callErr := syscall.Syscall(getModuleHandle, 0, 0, 0, 0); callErr != 0 {
    //        abort("Call GetModuleHandle", callErr)
    //    } else {
    //        handle = ret
    //    }
    //    return
    //}
    // windows下的第二种DLL方法调用
    func ShowMessage2(title, text string) {
        user32 := syscall.NewLazyDLL("user32.dll")
        MessageBoxW := user32.NewProc("MessageBoxW")
        MessageBoxW.Call(IntPtr(0), StrPtr(text), StrPtr(title), IntPtr(0))
    }
    func main() {
        //    defer syscall.FreeLibrary(kernel32)
        defer syscall.FreeLibrary(user32)
        //fmt.Printf("Retern: %d\n", MessageBox("Done Title", "This test is Done.", MB_YESNOCANCEL))
        num := MessageBox("Done Title", "This test is Done.", MB_YESNOCANCEL)
        fmt.Printf("Get Retrun Value Before MessageBox Invoked: %d\n", num)
        ShowMessage2("windows下的第二种DLL方法调用", "HELLO !")
        time.Sleep(3 * time.Second)
    }
    func init() {
        fmt.Print("Starting Up\n")
    }
    

    补充:go 调用windows dll 的三种方法

    第三种方法是从Go\src\internal\syscall\windows\sysdll源码中找到的,三种方法的具体区别还不是很明晰,

    初步判断:lazy应该是相当于动态库,其余两种直接把库加载到内存。

    package main
    import(
    	"fmt"
    	"syscall"
    	"time"
        "unsafe"
    )
    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 abort(funcname string, err syscall.Errno) {
        panic(funcname + " failed: " + err.Error())
    }
     
    var (
       
        user32, _     = syscall.LoadLibrary("user32.dll")
        messageBox, _ = syscall.GetProcAddress(user32, "MessageBoxW")
    )
     
    func IntPtr(n int) uintptr {
        return uintptr(n)
    }
     
    func StrPtr(s string) uintptr {
        return uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s)))
    }
     
    func MessageBox(caption, text string, style uintptr) (result int) {
        ret, _, callErr := syscall.Syscall9(messageBox,
            4,
            0,
            StrPtr(text),
            StrPtr(caption),
            style,
            0, 0, 0, 0, 0)
        if callErr != 0 {
            abort("Call MessageBox", callErr)
        }
        result = int(ret)
        return
    }
     
    //func GetModuleHandle() (handle uintptr) {
    //    if ret, _, callErr := syscall.Syscall(getModuleHandle, 0, 0, 0, 0); callErr != 0 {
    //        abort("Call GetModuleHandle", callErr)
    //    } else {
    //        handle = ret
    //    }
    //    return
    //}
     
    // windows下的第二种DLL方法调用
    func ShowMessage2(title, text string) {
        user32 := syscall.NewLazyDLL("user32.dll")
        MessageBoxW := user32.NewProc("MessageBoxW")
        MessageBoxW.Call(IntPtr(0), StrPtr(text), StrPtr(title), IntPtr(0))
    } 
     
    // windows下的第三种DLL方法调用
    func ShowMessage3(title, text string) {
        user32,_ := syscall.LoadDLL("user32.dll")
        MessageBoxW,_ := user32.FindProc("MessageBoxW")
        MessageBoxW.Call(IntPtr(0), StrPtr(text), StrPtr(title), IntPtr(0))
    }
     
    func main() {
        defer syscall.FreeLibrary(user32)
     
        num := MessageBox("Done Title", "This test is Done.", MB_YESNOCANCEL)
        fmt.Printf("Get Retrun Value Before MessageBox Invoked: %d\n", num)
        ShowMessage2("windows下的另一种DLL方法调用", "HELLO !")
    	
    	ShowMessage3("windows下的第三种DLL方法调用", "lyslyslys !")
     
        time.Sleep(3 * time.Second)
    }
     
    func init() {
        fmt.Print("Starting Up\n")
    }
     
    ​

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

    您可能感兴趣的文章:
    • Golang中switch语句和select语句的用法教程
    • Golang 编译成DLL文件的操作
    • golang调用c实现的dll接口细节分享
    • golang实践-第三方包为私有库的配置方案
    • 完美解决golang go get私有仓库的问题
    • golang gopm get -g -v 无法获取第三方库的解决方案
    • Golang: 内建容器的用法
    • golang switch语句的灵活写法介绍
    上一篇:go mod 使用私有gitlab群组的解决方案
    下一篇:golang调用c实现的dll接口细节分享
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Golang如何调用windows下的dll动态库中的函数 Golang,如何,调用,windows,下的,