I'm using Go to build a DLL.
I'm not able to implement windows DllMain entry point.
My goal is when an app loads the dll via LoadLibrary
to call the Test
method, the DllMain
will be called as well. However currently the app is kind of stuck in deadlock and nothing happens.
The app is quite simple python code
# App code
import ctypes
lib = ctypes.CDLL("./mydll.dll")
lib.Test()
Notes:
I am building using
go version go1.16.4 windows/amd64
and building using
go build -o mydll.dll --buildmode=c-shared
If I remove
DllMain
, everything works fine and app can call theTest
method successfully.I'm aware that I can
switch
case underDllMain
to specify conditions such as process attached, detached ...etc, I just wanted to keep it as simple as possible.
//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
can't be a Go function, since invoking a Go function the first time initializes the Go runtime, which can't be done in scope ofDllMain
(there are very few things that can be done in scope ofDllMain
).As a workaround, you can write
DllMain
in C and invoke Go code in a separate thread as in this example. But you can't synchronize with that thread in the scope ofDllMain
, doing so will again lead to a deadlock.There's also
_cgo_wait_runtime_init_done
, but it also is asynchronous.So if you need to perform some Go action synchronously on DLL attachment, you're out of luck. It's best to just define an "
Init
" exported function and call it before calling any other API.And of course, the idiomatic way in Go to initialize on load is via an
init()
function:Compile and run:
Output: