So this got asked here already. How to define a DllMain Entrypoint without emitting raw c code? My example doesn't works. Looking at the raw cache .c file it also doesn't looks correct at all.
import winim/inc/[windef, wincon]
proc mainThread(hModule: HINSTANCE) =
AllocConsole()
discard stdout.reopen("CONOUT$", fmWrite)
echo "Hello World"
proc entryPoint(hinstDLL: HINSTANCE, fwdreason: DWORD, lpvReserved: LPVOID): BOOL {.stdcall, exportc: "DllMain".} =
if fwdreason == DLL_PROCESS_ATTACH:
var t: Thread[HINSTANCE]
t.createThread(mainThread, hinstDLL)
result = TRUE
This example works. But I'm not sure what risks it would be to spawn a nim function in a raw windows thread.
proc mainThread {.exportc.} =
echo "Hello World"
{.emit:
["""
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved) {
switch (fwdreason) {
case DLL_PROCESS_ATTACH:
NimMain();
CloseHandle(
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)mainThread, hinstDLL, 0, 0)
);
case DLL_PROCESS_DETACH:
break;
}
return 1;
}
"""]
.}
" cpu:i386 is specified to compile the dll as 32bit" - of course, yes, that's what it means.
"And if yes, do you know if it is actually needed or it’s just for convenience of some type?" - maybe the game itself is 32-bit, then the DLL should be 32-bit as well
Also since I'm currently working with the emitting dllmain, does someone know if there are risks calling NimMain and then spawn a thread for the maincode?
I could imagine that the gc isn't running anymore or isnt aware of that I spawned Nimcode with windows' CreateThread
I guess I've found a workaround to access the library handle:
import winim/inc/[windef, wincon, winbase]
proc getCurrentModule: HINSTANCE =
discard GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS or
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
cast[LPWSTR](getCurrentModule),
result.addr,
)
proc mainThread =
AllocConsole()
discard stdout.reopen("CONOUT$", fmWrite)
echo getCurrentModule()
while true: discard
when isMainModule:
var t: Thread[void]
t.createThread(mainThread)
This code works
import winim/com
proc mainThread(hModule: HINSTANCE) =
AllocConsole()
discard stdout.reopen("CONOUT$", fmWrite)
while true:
echo "Hello World YEY", hModule
proc NimMain() {.cdecl, importc.}
proc DllMain(hModule: HINSTANCE, reasonForCall: DWORD, lpReserved: LPVOID): WINBOOL {.exportc, dynlib, stdcall.} =
case reasonForCall:
of DLL_PROCESS_ATTACH:
NimMain()
CreateThread(nil, nil, cast[LPTHREAD_START_ROUTINE](mainThread), cast[LPVOID](hModule), nil, nil)
of DLL_PROCESS_DETACH:
discard
of DLL_THREAD_ATTACH:
discard
of DLL_THREAD_DETACH:
discard
else:
discard
return TRUE