[Trick] DllMain нотификации без DLL
От: remark Россия http://www.1024cores.net/
Дата: 29.03.08 10:26
Оценка: 30 (2)
Задача: получать нотификации DLL_THREAD_ATTACH и DLL_THREAD_DETACH без создания собственной DLL.
Вопрос неоднократно встречался на этом форуме, но ответа не было.
Вот минимальный код. Проверил на MSVC2005/2008, в release/debug конфигурациях, со статическим и динамическим ран-таймом. Должно так же работать и на MSVC2003 и на MSVC6 (с небольшими изменениями). Единственная засада — со статическим ран-таймом не ловится нотификация DLL_PROCESS_ATTACH, но я думаю с этим можно жить.

#define _WIN32_WINNT 0x0500
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>

typedef void (NTAPI _TLSCB)(HINSTANCE, DWORD, PVOID);
_TLSCB on_tls_callback;

#pragma data_seg(push, old_seg)
#pragma data_seg(".CRT$XLB")
_TLSCB* p_thread_callback = on_tls_callback;
#pragma data_seg(pop, old_seg)

void NTAPI on_tls_callback(HINSTANCE, DWORD dwReason, PVOID)
{
  _TLSCB* volatile use_callback = p_thread_callback;
  static __declspec(thread) int volatile use_tls;
  use_tls = 0;

  static char const* ev[] = {"DLL_PROCESS_DETACH", "DLL_PROCESS_ATTACH", "DLL_THREAD_ATTACH", "DLL_THREAD_DETACH"};
  printf("%s (%d)\n", ev[dwReason], GetCurrentThreadId());
}

unsigned __stdcall thread(void*)
{
  printf("THREAD (%d)\n", GetCurrentThreadId());
  return 0;
}

int main()
{
  WaitForSingleObject((HANDLE)_beginthreadex(0, 0, &thread, 0, 0, 0), INFINITE);
  WaitForSingleObject((HANDLE)_beginthreadex(0, 0, &thread, 0, 0, 0), INFINITE);
}


Вывод:

DLL_PROCESS_ATTACH (3056)
DLL_THREAD_ATTACH (176)
THREAD (176)
DLL_THREAD_DETACH (176)
DLL_THREAD_ATTACH (2664)
THREAD (2664)
DLL_THREAD_DETACH (2664)
DLL_PROCESS_DETACH (3056)



Информация взята отсюда:
http://www.codeguru.com/Cpp/misc/misc/threadsprocesses/article.php/c6945__2/



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.