为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Go 中实现 DllMain 入口点

如何在 Go 中实现 DllMain 入口点

Go
桃花长相依 2022-09-05 17:25:48
我正在使用Go来构建一个DLL。我无法实现Windows DllMain入口点。我的目标是当应用程序通过LoadLibrary加载dll以调用该方法时,也会调用。但是,目前该应用程序陷入了死锁,没有任何反应。TestDllMain该应用程序是非常简单的python代码# App codeimport ctypeslib = ctypes.CDLL("./mydll.dll")lib.Test()笔记:我正在使用go version go1.16.4 windows/amd64和建筑使用go build -o mydll.dll --buildmode=c-shared如果我删除,一切正常,应用程序可以成功调用该方法。DllMainTest我知道我可以在案例下指定条件,例如流程附加,分离...等等,我只是想让它尽可能简单。switchDllMain//Go Codepackage mainimport "C"import (    "fmt"    "os")//export Testfunc Test() {    os.Create("fooFile")}//export DllMainfunc DllMain(a uintptr, b uint32, c uintptr) int32 {    return 1}func main() {}
查看完整描述

1 回答

?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

DllMain不能是 Go 函数,因为第一次调用 Go 函数会初始化 Go 运行时,这在 的范围内是无法完成的(在 的范围内可以做的事情很少)。DllMainDllMain


作为一种解决方法,您可以使用 C 编写代码,并在单独的线程中调用 Go 代码,如本示例所示。但是您无法在 的范围内与该线程同步,这样做将再次导致死锁。DllMainDllMain


还有_cgo_wait_runtime_init_done,但它也是异步的。


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


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


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


查看完整回答
反对 回复 2022-09-05
  • 1 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信