我正在使用 Go 构建 DLL。
我无法实现 Windows DllMain entry point .
我的目标是当应用程序通过 LoadLibrary
加载 dll 时要调用 Test
方法,DllMain
也会被调用。然而目前该应用程序陷入了僵局,什么也没有发生。
该应用程序是非常简单的 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
如果我删除
DllMain
,一切正常,应用程序可以成功调用Test
方法。我知道我可以在
DllMain
下switch
大小写来指定进程附加、分离等条件,我只是想保留尽可能简单。
//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 运行时,这不能在 DllMain
范围内完成(有 very few things 可以在 DllMain
范围内完成)。
作为解决方法,您可以编写 DllMain
在 C 中并在单独的线程中调用 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()
关于python - 如何在 Go 中实现 DllMain 入口点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67969401/