Thanks for your response. It seems logic to do what you say (aka lets make 
DllMain in C if Go does not let us control it)

So I did a main.c:
```
#include <windows.h>

extern void RunMe();

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID 
lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        RunMe();
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
```

Then a main.go that use main.c
```
package main

//#include "main.c"
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 main() {}
```

Then I compile by cd into the directory containing the main.go and main.c 
and running:
```
GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc go build 
-a -o ~/Desktop/dropamd64.dll -buildmode=c-shared
```

However I get an error from x86_64-w64-mingw32-gcc that DllMain is defined 
multiple time. I am not sure the issue is from DllMain though, because If I 
change DllMain to TestRudeus I get also the error TestRudeus is defined 
multiple time...

Le dimanche 10 novembre 2024 à 17:15:52 UTC+1, Jason E. Aten a écrit :

> 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/6b193e5a-7ae0-4c6d-8362-bfef9a2484f3n%40googlegroups.com.

Reply via email to