Golang创建Windows DLL的详细教程
Golang创建Windows DLL的详细教程 如何用Go语言创建Windows DLL
4 回复
上述相同的应用程序正在运行。
如何在 Go 语言中向函数传递多个 Excel 列
我希望在 Excel VBA 中调用这个 DLL
在Go语言中创建Windows DLL需要使用-buildmode=c-shared编译标志,并遵循特定的导出函数约定。以下是详细步骤:
1. 基本DLL创建示例
// main.go
package main
import "C"
import "fmt"
//export HelloWorld
func HelloWorld() {
fmt.Println("Hello from Go DLL!")
}
//export Add
func Add(a, b int) int {
return a + b
}
//export GetString
func GetString() *C.char {
return C.CString("String from Go DLL")
}
func main() {
// 必须包含main函数,但DLL中不会执行
}
2. 编译命令
# 编译为DLL
go build -buildmode=c-shared -o mydll.dll main.go
# 同时会生成.h头文件
3. 复杂数据类型示例
// advanced.go
package main
import "C"
import (
"unsafe"
"syscall"
)
//export ProcessData
func ProcessData(input *C.char, length C.int) *C.char {
// 转换C字符串到Go字符串
goStr := C.GoStringN(input, length)
// 处理数据
result := "Processed: " + goStr
// 返回C字符串(调用者需负责释放)
return C.CString(result)
}
//export FreeMemory
func FreeMemory(ptr unsafe.Pointer) {
C.free(ptr)
}
//export GetSystemInfo
func GetSystemInfo() *C.char {
version, _ := syscall.GetVersion()
info := fmt.Sprintf("Windows Version: %d", version)
return C.CString(info)
}
4. 回调函数支持
// callback.go
package main
import "C"
//export RegisterCallback
func RegisterCallback(callback C.PVOID) {
// 将C函数指针转换为Go函数
// 实际使用时需要更复杂的类型转换
fmt.Printf("Callback registered at: %v\n", callback)
}
//export CallWithCallback
func CallWithCallback() {
// 这里可以调用注册的回调函数
}
5. 内存管理注意事项
// memory.go
package main
import "C"
import (
"unsafe"
"runtime/debug"
)
//export AllocateBuffer
func AllocateBuffer(size C.int) unsafe.Pointer {
// 分配内存
return C.malloc(C.size_t(size))
}
//export ReleaseBuffer
func ReleaseBuffer(ptr unsafe.Pointer) {
C.free(ptr)
}
//export ForceGC
func ForceGC() {
debug.FreeOSMemory()
}
6. 编译选项优化
# 减小DLL体积
go build -buildmode=c-shared -ldflags="-s -w" -o mydll.dll main.go
# 指定架构
GOOS=windows GOARCH=amd64 go build -buildmode=c-shared -o mydll64.dll
GOOS=windows GOARCH=386 go build -buildmode=c-shared -o mydll32.dll
7. C++调用示例
// test.cpp
#include <windows.h>
#include <iostream>
#include "mydll.h" // 自动生成的头文件
typedef void(__stdcall* HelloWorldFunc)();
typedef int(__stdcall* AddFunc)(int, int);
int main() {
HINSTANCE hDLL = LoadLibrary(TEXT("mydll.dll"));
if (hDLL) {
HelloWorldFunc hello = (HelloWorldFunc)GetProcAddress(hDLL, "HelloWorld");
AddFunc add = (AddFunc)GetProcAddress(hDLL, "Add");
if (hello) hello();
if (add) std::cout << "Add(5, 3) = " << add(5, 3) << std::endl;
FreeLibrary(hDLL);
}
return 0;
}
关键要点:
- 使用
//export注释导出函数 - 函数名区分大小写
- CGO类型需要正确转换
- 字符串返回需要使用
C.CString,调用者负责释放 - 编译时必须使用
-buildmode=c-shared
这样创建的DLL可以被任何支持C调用约定的语言调用,包括C、C++、C#、Python等。

