I'll add that the one way I've found to address the "Go runtime cannot shut itself down" problem is to compile to wasm. WebAssembly hosts like the browser -- and running the wasm on a background web worker -- provide very nice ways of killing a web worker thread. I believe (but have not tried it), that wasm runtimes like wazero and wasmtime also provide means to pause and kill threads. https://github.com/tetratelabs/wazero/issues/421 may be relevant.
Runtimes like wazero compile the wasm to native code. These days they can, very impressively, execute at native or near native speed. Moreover, if you use tinygo (llvm under the covers) you can actually get wasm code to go faster (sometimes _much_ faster) than the native go compiler, even though you are going through a wasm layer. Since it would be vastly more portable than writing a DLL, you might explore the wasm approach if the wasm runtimes provide for what you are trying to do on Windows (which they well may not, but its worth exploring). On Sunday, November 10, 2024 at 3:14:52 PM UTC Jason E. Aten wrote: > Use CGO in your .go file, and then there, or in an adjacent C file, > actually do write a DllMain function; > https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain > > When fdwReason == DLL_PROCESS_ATTACH, then you know this is the first load > of the DLL > into this process. I think your subject line acknowledges that you known > this. > > Note that the APIENTRY annotation on the DllMain is required, in order to > get the > right calling convention. > > Be aware that the go runtime has a major problem when used inside a DLL: it > provides no way to shut itself down. This means that you can never unload > a DLL that you have loaded, even though Windows processes routinely do > unload DLLs. > > On XP or later you can use GetModuleHandleEx with the > GET_MODULE_HANDLE_EX_FLAG_PIN flag to prevent unloading of the DLL. > This means that your process won't crash on unload, but also that the > DLL will not actually be unloaded. In order to update the DLL, you must > kill the > process. > > On Sunday, November 10, 2024 at 1:54:16 PM UTC rudeus greyrat wrote: > >> I am trying to write DLL in go. I want it to execute some stuff when the >> DLL is attached to a process. >> >> I thought init() will be the equivalent of onattach but It seems I am >> wrong. >> >> I created this as a proof of concept: >> ``` >> package main >> >> import "C" >> import ( >> "syscall" >> >> "golang.org/x/sys/windows" >> ) >> >> //export RunMe >> func RunMe() { >> >> windows.MessageBox(windows.HWND(0), >> syscall.StringToUTF16Ptr("RunMe"), syscall.StringToUTF16Ptr("RunMe"), >> windows.MB_OK) >> } >> >> func init() { >> windows.MessageBox(windows.HWND(0), syscall.StringToUTF16Ptr("DLL >> Loaded"), syscall.StringToUTF16Ptr("DLL Load"), windows.MB_OK) >> } >> >> func main() {} >> ``` >> >> I compile on Linux with: >> ``` >> GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc go >> build -a -o ~/Desktop/dropamd64.dll -buildmode=c-shared cmd/dll64bit/main.go >> ``` >> >> I transfer on my Windows machine then here is the amazing result: >> *rundll32.exe Z:\dropamd64.dll -----> Nothing happens* >> *rundll32.exe Z:\dropamd64.dll,RunMe ------> Runs RunMe() and init() and >> I get 2 MessageBox* >> >> My question is, how to get a DLL that runs stuff only when process is >> attached ? >> >> There not a lot of official Golang doc about DLL (some few people write >> here and there some tutorials that are not always right and correct ...) So >> if you have some trustworthy doc please share. >> >> >> >> >> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/cf89bf1c-87a5-4e4a-b680-1cf026fa364fn%40googlegroups.com.