golang调用dll的接口三种方式小结

 更新时间:2025年07月24日 11:01:33   作者:两人一城  
本文介绍了在Go语言中使用syscall包的不同方法加载DLL文件,包括NewLazyDLL、MustLoadDLL、LoadLibrary以及它们在调用函数和处理不同数据类型转换中的应用,感兴趣的可以了解一下

1.使用syscall.NewLazyDLL()加载dll,使用接口函数.Call(uintptr类型的参数)来调用函数

(1)例如:调用初始化接口函数进行初始化操作

dllpath:="test.dll"
handle:=syscall.NewLazyDLL(dllpath)
//引号中的init即为dll中的函数方法
init:=handle.NewProc("init")
init.Call(BytePtr("C:\\dll"))

(2)将string类型转换为uintptr类型的函数如下

func BytePtr(str string)uintptr{
    s:=[]byte(str)
    return uintptr(unsafe.Pointer(&s[0]))
}

(3)可将调用初始化接口后得到的handle返回,后续调用该dll中其他接口方法时就可直接使用handle.NewProc("接口方法名"),具体如下

func call_Init()*syscall.LazyDLL{
    dllpath:="test.dll"
    handle:=syscall.NewLazyDLL(dllpath)
    //引号中的init即为dll中的函数方法
    init:=handle.NewProc("init")
    init.Call(BytePtr("C:\\dll"))
    return handle
}

2.使用syscall.MustLoadDLL(dllPath)加载dll,函数接口函数.Call(参数列表)调用

(1)例如:调用callByReference接口函数

func Call_PassByValue(n int) error {
	dllPath := "E:\\Code\\vs2015_project\\demo\\x64\\Release\\c2plusdll.dll"
	handle := syscall.MustLoadDLL(dllPath)
	callByReference := handle.MustFindProc("callByReference")
	ret, _, err := callByReference.Call(IntPtr(n))
	if err != nil {
		fmt.Println("DllTestDef的运算结果为:", ret)
	}
	return nil
}

(2)将int类型转换为uintptr类型的函数如下:

func IntPtr(n int)uintptr{
    return uintptr(n)
}

3.使用syscall.LoadLibrary(dllPath)函数加载dll,syscall.Syscall(...)函数调用具体的函数接口,如下:

(1)例如:调用获取数据接口函数

func get_ConnData()string{
    dllPath := "C:\\dll"
	handle, err := syscall.LoadLibrary(dllPath)
	if err != nil {
		fmt.Printf("Error: %s\n", err)
		return err
	}
	defer syscall.FreeLibrary(handle)

	export_conn, err := syscall.GetProcAddress(handle, "export_conn")
	if err != nil {
		fmt.Printf("Error: %s\n", err)
		return err
	}
	ret, _, _ := syscall.Syscall(export_conn, IntPtr("5"))
	if err != nil {
		fmt.Printf("Error: %s\n", err)
	}
	return uintptrTostr(ret)
}

(2)其中uintptrTostr函数为

func uintptrTostr(ptr uintptr)string{
    p:=(*byte)(unsafe.Pointer(ptr))
    data:=make([]byte,0)
    for *p!=0{
        data=append(data,*p)
        ptr+=unsafe.Sizeof(byte(0))
        p=(*byte)(unsafe.Pointer(ptr))
    }
    return string(data)
}

到此这篇关于golang调用dll的接口三种方式小结的文章就介绍到这了,更多相关golang调用dll接口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • Golang信号处理及如何实现进程的优雅退出详解

    Golang信号处理及如何实现进程的优雅退出详解

    这篇文章主要给大家介绍了关于Golang信号处理及如何实现进程的优雅退出的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-03-03
  • go语言使用gorilla/websocket实现websocket

    go语言使用gorilla/websocket实现websocket

    Gorilla WebSocket 是一个用于 Go 语言的 WebSocket 协议实现,而且是一个优秀的组件库,能快速实现websocket协议,下面就跟随小编一起来看看它的具体使用吧
    2025-04-04
  • 使用gin框架搭建简易服务的实现方法

    使用gin框架搭建简易服务的实现方法

    go语言web框架挺多的,本文就介绍了一下如何使用gin框架搭建简易服务的实现方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • golang给函数参数设置默认值的几种方式小结(函数参数默认值

    golang给函数参数设置默认值的几种方式小结(函数参数默认值

    在日常开发中我们有时候需要使用默认设置,下面这篇文章主要给大家介绍了关于golang给函数参数设置默认值的几种方式小结的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • Golang channel死锁的几种情况小结

    Golang channel死锁的几种情况小结

    本文主要介绍了Golang channel死锁的几种情况小结,详细的介绍了六种情况,具有一定的参考价值,感兴趣的可以了解一下
    2024-08-08
  • Golang必知必会之Go Mod命令详解

    Golang必知必会之Go Mod命令详解

    go mod可以使项目从GOPATH的强制依赖中独立出来,也就是说你的项目依赖不再需要放在在GOPATH下面了,下面这篇文章主要给大家介绍了关于Golang必知必会之Go Mod命令的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • Golang标准库time包日常用法小结

    Golang标准库time包日常用法小结

    本文主要介绍了Golang标准库time包日常用法小结,可以通过它们来获取当前时间、创建指定时间、解析时间字符串、控制时间间隔等操作,感兴趣的可以了解一下
    2023-11-11
  • Golang线程池与协程池的使用

    Golang线程池与协程池的使用

    在Golang中,线程池和协程池是非常常见且重要的概念,它们可以提高应用程序的并发处理能力和性能,减少资源的浪费,本文就来介绍一下Golang线程池与协程池的使用,感兴趣的可以了解一下
    2024-04-04
  • go modules中replace使用方法

    go modules中replace使用方法

    这篇文章主要为大家介绍了go modules中replace使用方法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • 从基础到高级全方位解析Go中反射的应用

    从基础到高级全方位解析Go中反射的应用

    本文我们将全面深入地探讨Go语言的反射机制,从反射的基础概念、为什么需要反射,到如何在Go中实现反射,以及在高级编程场景如泛型编程和插件架构中的应用,需要的可以参考下
    2023-10-10

最新评论