如何在 Go 中实现 DllMain 入口点

How to implement DllMain entry point in Go

我正在使用 Go 构建 DLL。

我无法实施 windows DllMain entry point

我的目标是当应用程序通过 LoadLibrary 加载 dll 以调用 Test 方法时,DllMain 也会被调用。但是目前该应用程序有点陷入僵局,没有任何反应。

应用程序非常简单python代码

# App code
import ctypes
lib = ctypes.CDLL("./mydll.dll")
lib.Test()

备注:

//Go Code
package main

import "C"

import (
    "fmt"
    "os"
)

//export Test
func Test() {
    os.Create("fooFile")
}


//export DllMain
func DllMain(a uintptr, b uint32, c uintptr) int32 {
    return 1
}

func main() {
}

DllMain 不能是 Go 函数,因为第一次调用 Go 函数会初始化 Go 运行time,这不能在 DllMain 范围内完成(very few things 可以在 DllMain 范围内完成)。

作为解决方法,您可以用 C 编写 DllMain 并在 单独的线程 中调用 Go 代码,就像在 this example 中一样。但是你不能在DllMain范围内与那个线程同步,这样做会再次导致死锁。

还有_cgo_wait_runtime_init_done,不过也是异步的

因此,如果您需要在 DLL 附件上同步执行一些 Go 操作,那您就不走运了。最好只定义一个“Init”导出函数并在调用任何其他 API.

之前调用它

当然,Go 中惯用的加载初始化方式是通过 init() function:

package main

import "C"

import (
    "fmt"
)

func init() {
    fmt.Println("init()")
}

//export Test
func Test() {
    fmt.Println("Test()")
}

func main() {
}

编译并运行:

go build -o mydll.dll --buildmode=c-shared
rundll32 mydll,Test

输出:

init()
Test()