如何在 Go 中实现 DllMain 入口点

我正在使用Go来构建一个DLL。


我无法实现Windows DllMain入口点。


我的目标是当应用程序通过LoadLibrary加载dll以调用该方法时,也会调用。但是,目前该应用程序陷入了死锁,没有任何反应。TestDllMain


该应用程序是非常简单的python代码


# App code

import ctypes

lib = ctypes.CDLL("./mydll.dll")

lib.Test()

笔记:


我正在使用


go version go1.16.4 windows/amd64

和建筑使用


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

如果我删除,一切正常,应用程序可以成功调用该方法。DllMainTest


我知道我可以在案例下指定条件,例如流程附加,分离...等等,我只是想让它尽可能简单。switchDllMain


//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() {

}


桃花长相依
浏览 106回答 1
1回答

哆啦的时光机

DllMain不能是 Go 函数,因为第一次调用 Go 函数会初始化 Go 运行时,这在 的范围内是无法完成的(在 的范围内可以做的事情很少)。DllMainDllMain作为一种解决方法,您可以使用 C 编写代码,并在单独的线程中调用 Go 代码,如本示例所示。但是您无法在 的范围内与该线程同步,这样做将再次导致死锁。DllMainDllMain还有_cgo_wait_runtime_init_done,但它也是异步的。因此,如果您需要对 DLL 附件同步执行一些 Go 操作,那么您就不走运了。最好只定义一个“”导出的函数,并在调用任何其他 API 之前调用它。Init当然,Go 中在加载时初始化的惯用方式是通过 init() 函数:package mainimport "C"import (    "fmt")func init() {    fmt.Println("init()")}//export Testfunc Test() {    fmt.Println("Test()")}func main() {}编译并运行:go build -o mydll.dll --buildmode=c-sharedrundll32 mydll,Test输出:init()Test()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go