golang怎么编译、调用dll文件

在Go语言中编译和调用DLL文件,通常需要使用`cgo`工具。以下是一个简单的步骤:

1. 确保你的DLL文件是C或C++编写的,因为Go通过`cgo`与C/C++代码交互。
2. 在Go代码中使用`#cgo CFLAGS: -I/path/to/include`来指定头文件路径。
3. 使用`#include "filename.h"`来包含头文件。
4. 使用`// +build windows`来确保代码仅在Windows平台上编译。
5. 使用C函数原型声明来调用DLL中的函数。

示例代码如下:

```go
// #cgo CFLAGS: -I/path/to/include
// #include "example.h"
import "C"

// +build windows

func main() {
// 调用DLL中的函数
result := C.example_function(C.int(10))
println("Result from DLL: ", C.GoString(result))
}
```

确保替换`/path/to/include`和`example.h`为实际路径和头文件名,以及替换`example_function`为实际的DLL函数名。

注意:如果你的DLL不是用C或C++编写的,你可能需要使用其他方法,如使用Go的FFI(Foreign Function Interface)库或其他工具。


编译

exportgo.go

package main


import "C"

/*
   export PrintBye 的意思是将PrintBye方法通过PrintBye名暴露出去
*/
//export PrintBye
func PrintBye() {
   /*
      这里是只能用println
      不能用:log.Println()和fmt.Println()
   */
   println("From DLL: Bye!")
}

//export Sum
func Sum(a C.int, b C.int) C.int {
   return a   b
}

//export Sub
func Sub(a C.int, b C.int) C.int {
   return a - b
}

//export Hello
func Hello(a C.int, b C.int) C.int {
   return a * b
}

func main() {
   // Need a main function to make CGO compile package as C shared library
}

编译

>go build -buildmode=c-shared -o exportgo.dll exportgo.go

编译完成后,生成exportgo.dll和exportgo.h

调用

Called.go

package main


import "C"
import (
    "log"
    "syscall"
)

func main() {
    log.SetFlags(log.LstdFlags | log.Lshortfile)
    F4(50,30)
    F5(50,30)
    F6()
}
func F4(int1, int2 int) {
    log.Println(int1, int2)
    //引入dll文件方法1
    dll := syscall.MustLoadDLL("exportgo.dll")
    //使用完后要释放
    defer dll.Release()
    //调用dll的方法Sum
    proc := dll.MustFindProc("Sum")
    //使用sum函数,传递参数int1和int2
    call, u, err := proc.Call(uintptr(int1), uintptr(int2))
    //输出结果call
    log.Println(call)
    log.Println(u)
    log.Println(err)
}
func F5(int1, int2 int) {
    //引入dll文件方法2
    dll := syscall.NewLazyDLL("exportgo.dll")
    //调用dll的方法Sub
    proc := dll.NewProc("Sub")
    //使用Sub函数,传递参数int1和int2
    r, err, msg := proc.Call(uintptr(int1), uintptr(int2))
    //输出结果r
    log.Println(r)
    log.Println(err)
    log.Println(msg)
}
func F6() {
    //引入dll文件
    dll := syscall.NewLazyDLL("exportgo.dll")
    //调用dll的方法PrintBye
    proc := dll.NewProc("PrintBye")
    //调用dll的方法,不传递任何值
    r, err, msg := proc.Call()
    //输出结果r
    log.Println(r)
    log.Println(err)
    log.Println(msg)
}

执行结果

2022/03/26 14:48:00 Called.go:16: 50 30

2022/03/26 14:48:00 Called.go:26: 80
2022/03/26 14:48:00 Called.go:27: 8791506616320
2022/03/26 14:48:00 Called.go:28: The operation completed successfully.
2022/03/26 14:48:00 Called.go:38: 20
2022/03/26 14:48:00 Called.go:39: 8791503994880
2022/03/26 14:48:00 Called.go:40: The operation completed successfully.
From DLL: Bye!
2022/03/26 14:48:00 Called.go:50: 0
2022/03/26 14:48:00 Called.go:51: 8791503994880
2022/03/26 14:48:00 Called.go:52: The operation completed successfully.

相关推荐

  • 个人所得税汇算清缴补税怎么补(个人所得税更正申报退税)

    个人所得税汇算清缴补税怎么补(个人所得税更正申报退税) 央视网消息(记者 王莉莉):2021年度个人所得税综合所得年度汇算将于3月1日开始,6月30日结束,跨度4个月. 个人所得税改革从2018年10月开始实施,再过三天,2021年度个人所得税综合所得年度汇算即将开启,那么,与每个人都关系重大的年度汇算到底是什么?采访中,国家税务总局山西税务局个税处相关负责人表示,个人所得税年度汇算就是对去年预扣预缴过的个人所得税算个总账,多退少补. 为什么要做这个年度汇算?据介绍,因为个人在预扣预缴阶段已经交过的个人所得税,跟按年算总账应该交的个人所得税可能不一样 ...

  • 照片上传过大,怎样压缩(图片过大上传不了,怎么压缩变小)

    照片上传过大,怎样压缩(图片过大上传不了,怎么压缩变小) 平时在网上的注册账号中经常会遇到需要上传身份证或其他图片, 身份证用手机拍好上传到电脑上,显示也就好几M,不方便上传,容量太大,经常上传失败.大家肯定会想到有软件来压缩一下图片,我在网上也下好多种压缩图片的软件,测试后,压缩后效果也来太好.后来无意间想到了一个方法,测试了一下效果不错,操作也很简单.大家肯定想要知道方法吧,方法就是用截图法来压缩图片,我这里就不用身份证来演示,身份证有个人隐私的信息,我这里就用一张图片来演示,方法用在身份证绝对可以用的.先准备一张你要压缩的图片,比如:IMG_91 ...

  • Word怎么压缩图片使文档变小

    Word怎么压缩图片使文档变小 Word中怎么压缩图片使文档空间变小 操作方法 01 首先我们找到桌面上的Word文档 02 双击打开它 03 我们点击插入图片,插入一张图片进来 04 插入之后,直接先保存一份 05 然后我们点击图片,点击格式,压缩图片 06 弹出如图选框,我们直接点击选项 07 现在再保存一份,不要和刚才保存的名字一样,我们可以看到两个文档的内容虽然一样,但大小是不一样的,这样就减少了我们的储存空间 ...

  • 用PS如何将图片像素不变,占用空间变小?

    用PS如何将图片像素不变,占用空间变小? 很多时候,我们遇到个问题,图片上传到网站提示,"不得超过5M"等等类似问题,今天我们要解决的是如何在不改变图片像素大小的情况下,把图片所占内存变小. 操作方法 01 找到需要调整的图片,点击属性看一下它的详细信息,如下图 02 用PS打开图片,或者快捷键ctrl+o打开图片,如下图 03 点击菜单栏[文件],存储为Web和设备所用格式,如下图 04 选择JPEG,调整品质大小,对应左下角有文件内存大小,(看个人需求)如下图 05 然后点击右下角的存储,我们同时发现像素也没有变 ... ...

  • 孩子死活记不住英语单词(为什么有些单词怎么都记不住)

    孩子死活记不住英语单词(为什么有些单词怎么都记不住) 拿着单词列表按顺序背单词又枯燥又低效,往往背到abandon就放弃了,再到abortion就流产了.即便能坚持天天背,背完没两天又忘了.那有没有更高效的方法呢?其实英语单词跟汉语一样是有偏旁部首的,只要记住它们,遇到不会的单词就可以猜,所以要记的东西就大大减少了.这些偏旁部首就是词根词缀,因为英语融合了各种语言,比如希腊语.拉丁语.法语.德语,所以词根也来自不同的语言,根据词根在源语言中的意思来解释英语单词意思的方法叫词源学.按照词源学记单词又快又有意思.拉丁语cedere意思为"放弃 ... ...

  • VMW虚拟主机如何同步NTP

    VMW虚拟主机如何同步NTP 10.1 ESX Server服务器主机NTP配置方法1.选中要实施的虚拟机如192.168.0.252,选择时间配置-属性2.选中"NTP客户端已启用"选项,然后选择"选项"                3.常规设置中选择"与主机一起启动和停止"4.NTP设置中选择添加,输入NTP服务器IP地址5.选择"重启NTP服务以应用更改"6.点击刷新后,确认"日期和时间"."NTP客户端&q ... ...