golang编译为dll与调用dll简单样例

==前置准备==

1、golang版本:1.18

2、安装MinGW(我的环境本身已经安装好了,没有验证不安装是否可以生成)

 

==编译为DLL==

【代码样例】

package main

import "C"

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

func main() {
    // 编译命令
    // go build -buildmode=c-shared -o mydll.dll .\build_to_dll.go
}

 

注意事项:

1、需要有import "C"

2、输出函数需要有//export,同时需要注意//与export之间不能有空格

3、需要有main函数,可以不写,main函数不是对外输出函数

 

【编译命令】

go build -buildmode=c-shared -o mydll.dll .\build_to_dll.go

 

正常编译后会生成.dll及.h文件,如下图所示

 

==调用DLL==

【代码样例】

package main

import (
    "fmt"
    "syscall"
    "unsafe"
)

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

func Int2IntPtr(n int) uintptr {
    return uintptr(unsafe.Pointer(&n))
}

func IntPtr2Ptr(n *int) uintptr {
    return uintptr(unsafe.Pointer(n))
}

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

func main() {
    dllPath := "D:\\work\\10_Git\\golang\\src\\golang-demo\\dll\\mydll.dll"
    handle, err := syscall.LoadLibrary(dllPath)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    defer func(handle syscall.Handle) {
        _ = syscall.FreeLibrary(handle)
    }(handle)

    sum, err := syscall.GetProcAddress(handle, "Sum")
    if err != nil {
        fmt.Println(err.Error())
        return
    }

    r1, r2, e := syscall.SyscallN(sum, 2, IntPtr(4), IntPtr(5), 0)
    if e != 0 {
        fmt.Println(err.Error())
        return
    }

    fmt.Println(fmt.Sprintf("返回结果为:r1=%v, r2=%v, e=%v", r1, r2, e))
}

 

【执行结果】

 

--END--

posted @ 2022-12-07 15:37  大墨垂杨  阅读(3101)  评论(0编辑  收藏  举报