digitalmars.D.learn - Can't find windows' CreateThread function / concurrency.spawn crashes
- alkololl (13/13) Jan 01 2016 Hey there and a happy new year,
- alkololl (65/65) Jan 01 2016 Here is my code:
- Adam D. Ruppe (17/18) Jan 01 2016 std.c.windows is basically useless. The new version should have
- alkololl (6/24) Jan 01 2016 Thanks, I replaced LPSECURITY_ATTRIBUTES and
- Adam D. Ruppe (6/7) Jan 01 2016 I'm not sure, but in the switch you posted, you didn't handle the
- alkololl (5/12) Jan 02 2016 Thanks for your reply. I replaced my switch statement with the
- Rainer Schuetze (9/22) Jan 02 2016 D needs "implicite thread local storage" to implement thread local
- alkololl (5/25) Jan 02 2016 What? I'm actually running Windows 7. For me it's inevitable to
- Rainer Schuetze (5/26) Jan 04 2016 If you run Windows 7, I guess the runtime patch is not the issue here.
Hey there and a happy new year, I wrote a C++ Dll which gets injecrted into another process. Now I want to port that Dll to D. In my C++ Dll I used a while loop which captures all keystrokes via GetAsyncKeyState and waited for F7 to be pressed and lastly unloads the dll via FreeLibraryAndExitThread. This while loop needs to be run out of an dedicated thread. I've found that std.c.windows.windows doesn't include a definition for Windows API's CreateThread method and the usage of concurrency.spawn crashes my host application (in which the Dll gets injected to). How am I supposed to create a thread in the host application? Or are there other ways to capture the F7 keystroke?
Jan 01 2016
Here is my code: // File dllmain.d module dllmain; import core.runtime; import std.c.stdlib; import std.string; import std.c.windows.windows; import honmod; private HINSTANCE g_hInst; extern (Windows) BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved) { g_hInst = hInstance; switch (ulReason) { case DLL_PROCESS_ATTACH: Runtime.initialize(); break; case DLL_PROCESS_DETACH: Runtime.terminate(); break; default: } return true; } static this() { honmod.initialize(g_hInst); MessageBoxA(null, "Dll Injection successful", "", MB_OK); } static ~this() { MessageBoxA(null, "Dll ejected", "", MB_OK); } // File honmod module honmod; import std.concurrency; import std.c.windows.windows; import core.thread; private HINSTANCE _hModule; // The quit thread waits until F7 gets pressed and then frees the module private void quitThread() { while (true) { // KeyDown if (GetAsyncKeyState(VK_F7) & 0x0001) { break; } Sleep(1); } FreeLibraryAndExitThread(_hModule, 0); } void initialize(HINSTANCE hModule) { _hModule = hModule; // Spawn the quit thread new Thread(&quitThread).start(); }
Jan 01 2016
On Friday, 1 January 2016 at 22:02:46 UTC, alkololl wrote:I've found that std.c.windows.windows doesn't include astd.c.windows is basically useless. The new version should have it in core.sys.windows.windows though I'm not sure if it has actually been released yet. If it isn't in there on your version, you can also just define teh function yourself somewhere and use it. Add to your module: extern(Windows) HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); and then call it. If a type isn't defined you can replace it with void* usually.
Jan 01 2016
On Friday, 1 January 2016 at 22:45:20 UTC, Adam D. Ruppe wrote:On Friday, 1 January 2016 at 22:02:46 UTC, alkololl wrote:Thanks, I replaced LPSECURITY_ATTRIBUTES and LPTHREAD_START_ROUTINE with void* and it works now. Anyhow the method FreeLibraryAndExitThread, which worked perfectly in the C++ Dll, doesn't unload the D Dll properly (the call has no effect at all). Why is that?I've found that std.c.windows.windows doesn't include astd.c.windows is basically useless. The new version should have it in core.sys.windows.windows though I'm not sure if it has actually been released yet. If it isn't in there on your version, you can also just define teh function yourself somewhere and use it. Add to your module: extern(Windows) HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); and then call it. If a type isn't defined you can replace it with void* usually.
Jan 01 2016
On Saturday, 2 January 2016 at 00:32:20 UTC, alkololl wrote:Why is that?I'm not sure, but in the switch you posted, you didn't handle the DLL_THREAD_ATTACH and DLL_THREAD_DETACH cases, the runtime might be incrementing the refcount there. Check this out: http://wiki.dlang.org/Win32_DLLs_in_D
Jan 01 2016
On Saturday, 2 January 2016 at 01:44:46 UTC, Adam D. Ruppe wrote:On Saturday, 2 January 2016 at 00:32:20 UTC, alkololl wrote:Thanks for your reply. I replaced my switch statement with the one behind the link you left but the result (no result) stays the same. The Dll doesn't get unloaded. Not until I close the host application.Why is that?I'm not sure, but in the switch you posted, you didn't handle the DLL_THREAD_ATTACH and DLL_THREAD_DETACH cases, the runtime might be incrementing the refcount there. Check this out: http://wiki.dlang.org/Win32_DLLs_in_D
Jan 02 2016
On 02.01.2016 16:34, alkololl wrote:On Saturday, 2 January 2016 at 01:44:46 UTC, Adam D. Ruppe wrote:D needs "implicite thread local storage" to implement thread local variables, but Windows XP and earlier versions do not support this for DLLs dynamically loaded through LoadLibrary. The D runtime implements the part necessary for loading, but does not support unloading. As a consequence it sets the DLL to never unload. If you are actually running XP, you can check https://github.com/denis-sh/hooking. IIRC Denis Shelomovskij implemented the missing parts.On Saturday, 2 January 2016 at 00:32:20 UTC, alkololl wrote:Thanks for your reply. I replaced my switch statement with the one behind the link you left but the result (no result) stays the same. The Dll doesn't get unloaded. Not until I close the host application.Why is that?I'm not sure, but in the switch you posted, you didn't handle the DLL_THREAD_ATTACH and DLL_THREAD_DETACH cases, the runtime might be incrementing the refcount there. Check this out: http://wiki.dlang.org/Win32_DLLs_in_D
Jan 02 2016
On Saturday, 2 January 2016 at 16:42:46 UTC, Rainer Schuetze wrote:On 02.01.2016 16:34, alkololl wrote:What? I'm actually running Windows 7. For me it's inevitable to not unload the D Dll dynamically. Isn't there some kind of workaround or a sneaky hack to solve this?On Saturday, 2 January 2016 at 01:44:46 UTC, Adam D. Ruppe wrote:D needs "implicite thread local storage" to implement thread local variables, but Windows XP and earlier versions do not support this for DLLs dynamically loaded through LoadLibrary. The D runtime implements the part necessary for loading, but does not support unloading. As a consequence it sets the DLL to never unload. If you are actually running XP, you can check https://github.com/denis-sh/hooking. IIRC Denis Shelomovskij implemented the missing parts.[...]Thanks for your reply. I replaced my switch statement with the one behind the link you left but the result (no result) stays the same. The Dll doesn't get unloaded. Not until I close the host application.
Jan 02 2016
On 02.01.2016 18:41, alkololl wrote:On Saturday, 2 January 2016 at 16:42:46 UTC, Rainer Schuetze wrote:If you run Windows 7, I guess the runtime patch is not the issue here. Have you tried to load the DLL explicitely (without injecting it)? Does it unload correctly in this case? If not, it should ease debugging the problem.On 02.01.2016 16:34, alkololl wrote:What? I'm actually running Windows 7. For me it's inevitable to not unload the D Dll dynamically. Isn't there some kind of workaround or a sneaky hack to solve this?On Saturday, 2 January 2016 at 01:44:46 UTC, Adam D. Ruppe wrote:D needs "implicite thread local storage" to implement thread local variables, but Windows XP and earlier versions do not support this for DLLs dynamically loaded through LoadLibrary. The D runtime implements the part necessary for loading, but does not support unloading. As a consequence it sets the DLL to never unload. If you are actually running XP, you can check https://github.com/denis-sh/hooking. IIRC Denis Shelomovskij implemented the missing parts.[...]Thanks for your reply. I replaced my switch statement with the one behind the link you left but the result (no result) stays the same. The Dll doesn't get unloaded. Not until I close the host application.
Jan 04 2016