返回顶部
首页 > 资讯 > 后端开发 > GO >Golang如何调用windows下的dll动态库中的函数
  • 400
分享到

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

2024-04-02 19:04:59 400人浏览 八月长安
摘要

使用syscall调用 package main import ( "fmt" "syscall" "time" "unsafe" ) const

使用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")
}
 
​

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

您可能感兴趣的文档:

--结束END--

本文标题: Golang如何调用windows下的dll动态库中的函数

本文链接: https://lsjlt.com/news/125163.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Golang如何调用windows下的dll动态库中的函数
    使用syscall调用 package main import ( "fmt" "syscall" "time" "unsafe" ) const...
    99+
    2024-04-02
  • python如何调用dll库中的函数
    在python中使用ctypes模块调用dll库中函数的方法首先,在Python项目中引入ctypes模块;from ctypes import *ctypes模块引入后,在Python中加载dll库;Objdll = ctypes.Win...
    99+
    2024-04-02
  • C++DLL动态库的创建与调用(类库,隐式调用)
    目录1、创建库工程2、添加头文件3、添加cpp文件4、编译dll工程5、创建调用工程6、调用工程 添加cpp文件1、创建库工程 2、添加头文件 ClassDll.h // 宏定义...
    99+
    2024-04-02
  • 在动态库中调用外部函数的方法
    本篇内容介绍了“在动态库中调用外部函数的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!愉快的玩耍比如:...
    99+
    2024-04-02
  • 如何在 PHP OOP 中动态调用函数
    在 php oop 中,动态调用方法可通过两个函数实现:call_user_func:将方法名和参数逐个传递,获取要调用的方法名和参数数组,再调用此函数。call_user_func_a...
    99+
    2024-04-10
    oop 动态调用
  • Linux中如何使用动态库函数
    这篇文章将为大家详细讲解有关Linux中如何使用动态库函数,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Linux动态库函数的详解加载动态库void *dlopen(const&n...
    99+
    2023-06-09
  • 关于python调用c++动态库dll时的参数传递问题
    目录stringcv::Matstring C++生成dll代码: #include <iostream> extern "C" __declspec(dllexport...
    99+
    2024-04-02
  • 如何在 Golang 中使用数据库回调函数?
    在 golang 中使用数据库回调函数可以实现:在指定数据库操作完成后执行自定义代码。通过单独的函数添加自定义行为,无需编写额外代码。回调函数可用于插入、更新、删除和查询操作。必须使用 ...
    99+
    2024-05-14
    数据库 回调函数 mysql git golang
  • python调用c++动态库dll时的参数传递问题怎么解决
    本篇内容介绍了“python调用c++动态库dll时的参数传递问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!stringC++生...
    99+
    2023-06-29
  • golang函数中回调函数的作用
    go 中回调函数在函数中作为参数传递,用于在特定事件或条件发生后执行特定动作,增强代码的可重用性和扩展性。主要作用为:事件处理:作为事件侦听器的回调处理程序,在事件发生时采取动作。数据处...
    99+
    2024-04-25
    golang 回调函数 git
  • Golang中如何动态调用结构体的所有方法?
    哈喽!今天心血来潮给大家带来了《Golang中如何动态调用结构体的所有方法?》,想必大家应该对Golang都不陌生吧,那么阅读本文就都不会很困难,以下内容主要涉及到,若是你正在学习Golang,千万...
    99+
    2024-04-05
  • P/Invoke之C#调用动态链接库DLL的方法是什么
    这篇文章主要介绍了P/Invoke之C#调用动态链接库DLL的方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇P/Invoke之C#调用动态链接库DLL的方法是什么文章都会有所收获,下面我们一起来看看吧...
    99+
    2023-07-05
  • golang函数中的延迟调用是如何实现的?
    golang 中函数延迟调用由 defer 关键字实现,该关键字将函数调用延迟到当前函数退出时执行。通过在栈中添加一个 defer 函数,存储延迟调用的函数和参数,确保退出函数后才调用延...
    99+
    2024-05-23
    golang 延迟调用
  • 如何调试通过网络调用的 Golang 函数?
    如何调试通过网络调用的 golang 函数?有以下两种方法:使用日志记录:添加 log.printf 语句以记录函数调用、返回结果或错误。使用跟踪:启用 -tags go.net.tra...
    99+
    2024-04-17
    调试 golang
  • C++ 函数调试详解:如何调试包含动态内存分配的函数中的问题?
    在 c++++ 中调试包含动态内存分配的函数时,可使用:调试器(gdb/lldb)检查内存分配/释放(valgrind)断言异常处理实战案例:函数 free_twice 错误:释放已释放...
    99+
    2024-05-04
    c++ 函数调试 linux
  • Go动态调用函数的实例教程
    目录前言JavaScript 动态调用函数Go 中动态调用方法前言 经常在开发的时候会遇到这样的场景,几个模块的都有相同的方法,但会因为不同的类型的需要调用不同模块的方法。使用一个 ...
    99+
    2023-01-03
    Go动态调用函数 Go动态调用
  • golang函数中的调度器是如何实现的?
    go 语言的调度器是一个非抢占式调度器,可管理 goroutine 的执行。它维护一个按优先级组织的 goroutine 队列:当一个 goroutine 完成时,它会返回调度器。调度器...
    99+
    2024-05-24
    golang 调度器
  • Matplotlib库基础中如何自动调整函数
    这篇文章给大家介绍Matplotlib库基础中如何自动调整函数,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。在matplotlib中,轴Axes的位置以标准化图形坐标指定,可能发生的情况是轴标签、标题、刻度标签等等会超...
    99+
    2023-06-02
  • Go 中调用的函数如何访问调用函数的参数?
    Go 中调用的函数可以通过函数参数来获取调用函数的参数。在 Go 中,参数可以通过传值或传引用的方式传递给函数,函数可以通过参数来获取调用者传递的值或指针。如果参数是值类型,函数内部的...
    99+
    2024-02-09
  • PHP 函数的动态调用技巧是什么?
    php 动态调用函数是一种强大的特性,允许您根据变量值或输入动态调用函数。您可以使用 call_user_func() 函数,其中第一个参数是函数名称,后面是函数参数。动态调用函数可提高...
    99+
    2024-04-11
    函数 php
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作