我正在使用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()
- 1 回答
- 0 关注
- 105 浏览
添加回答
举报
0/150
提交
取消