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)库或其他工具。
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.