Golang创建Windows DLL的详细教程

Golang创建Windows DLL的详细教程 如何用Go语言创建Windows DLL

4 回复

谢谢。我会尝试。

更多关于Golang创建Windows DLL的详细教程的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


上述相同的应用程序正在运行。

如何在 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;
}

关键要点:

  1. 使用//export注释导出函数
  2. 函数名区分大小写
  3. CGO类型需要正确转换
  4. 字符串返回需要使用C.CString,调用者负责释放
  5. 编译时必须使用-buildmode=c-shared

这样创建的DLL可以被任何支持C调用约定的语言调用,包括C、C++、C#、Python等。

回到顶部