FAQ:WinAPI VCPP:значение переменной для вызывающего процесса/потока из своей собственной DLL — различия между версиями
RXL (обсуждение | вклад) м («FAQ: WinAPI VCPP: значение переменной для вызывающего процесса/потока из своей собственной DLL» переименована в «[[FAQ:WinAPI VCPP:значение переменной ) |
|||
(не показано 7 промежуточных версий 2 участников) | |||
Строка 1: | Строка 1: | ||
− | === Каким образом можно установить значение переменной для вызывающего процесса | + | ===Каким образом можно установить значение переменной для вызывающего процесса или потока из своей собственной DLL?=== |
− | Проблема вызвана тем, что каждая | + | ''Проблема заключается в том, что несмотря на то, что все линкуется нормально, значение переменной процесса не изменяется, когда я его устанавливаю вручную в библиотеке.'' |
+ | |||
+ | |||
+ | Проблема вызвана тем, что каждая прилинкованная libc (одна линкуется в исполняемый файл, ещё одна в dll) содержит свою копию переменной. | ||
1) Можно воспользоваться динамически подгружаемой библиотекой С runtime. Для этого приложение и dll надо компилировать с ключом /MD (или MDd для отладки). В таком случае переменная будет общей для приложения и dll. | 1) Можно воспользоваться динамически подгружаемой библиотекой С runtime. Для этого приложение и dll надо компилировать с ключом /MD (или MDd для отладки). В таком случае переменная будет общей для приложения и dll. | ||
− | 2) Можно в основном модуле программы (тот, который станет .exe) сделать "дырку" (backdoor), через которую присваивать переменной (int errno) значение: < | + | 2) Можно в основном модуле программы (тот, который станет .exe) сделать "дырку" (backdoor), через которую присваивать переменной (int errno) значение: |
+ | |||
+ | <syntaxhighlight lang="cpp"> | ||
+ | __declspec(dllexport) void set_errno(int code) | ||
+ | { | ||
+ | errno = code; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | В dll, при подключении к процессу, надо извлечь из модуля программы указатель на эту функцию. | ||
+ | |||
+ | <syntaxhighlight lang="cpp"> | ||
+ | typedef void (*SETINT)(int); | ||
+ | SETINT g_set_errno=0; | ||
+ | void set_errno_in_exe(int code) | ||
+ | { | ||
+ | if(g_set_errno) g_set_errno(code); | ||
+ | } | ||
+ | |||
+ | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) | ||
+ | { | ||
+ | HANDLE hModule; // Handle to the main module | ||
+ | if(fdwReason == DLL_PROCESS_ATTACH ) | ||
+ | { | ||
+ | hModule = GetModuleHandle(NULL); | ||
+ | if (hModule == NULL) return FALSE; | ||
+ | g_set_errno = (SETINT) GetProcAddress(hModule, "set_errno"); | ||
+ | } | ||
+ | return TRUE; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | В нужном месте в dll, вместо присваивания errno, нужно вызывать внешнюю функцию. | ||
+ | |||
+ | <syntaxhighlight lang="cpp"> | ||
+ | void inside_dll_func() | ||
+ | { | ||
+ | ... | ||
+ | ... | ||
+ | set_errno_in_exe(ERROR_CODE); | ||
+ | ... | ||
+ | } | ||
+ | </syntaxhighlight> | ||
− | + | [[Category:FAQ:WinAPI VCPP]] |
Текущая версия на 18:54, 5 октября 2008
Каким образом можно установить значение переменной для вызывающего процесса или потока из своей собственной DLL?
Проблема заключается в том, что несмотря на то, что все линкуется нормально, значение переменной процесса не изменяется, когда я его устанавливаю вручную в библиотеке.
Проблема вызвана тем, что каждая прилинкованная libc (одна линкуется в исполняемый файл, ещё одна в dll) содержит свою копию переменной.
1) Можно воспользоваться динамически подгружаемой библиотекой С runtime. Для этого приложение и dll надо компилировать с ключом /MD (или MDd для отладки). В таком случае переменная будет общей для приложения и dll.
2) Можно в основном модуле программы (тот, который станет .exe) сделать "дырку" (backdoor), через которую присваивать переменной (int errno) значение:
__declspec(dllexport) void set_errno(int code) { errno = code; }
В dll, при подключении к процессу, надо извлечь из модуля программы указатель на эту функцию.
typedef void (*SETINT)(int); SETINT g_set_errno=0; void set_errno_in_exe(int code) { if(g_set_errno) g_set_errno(code); } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) { HANDLE hModule; // Handle to the main module if(fdwReason == DLL_PROCESS_ATTACH ) { hModule = GetModuleHandle(NULL); if (hModule == NULL) return FALSE; g_set_errno = (SETINT) GetProcAddress(hModule, "set_errno"); } return TRUE; }
В нужном месте в dll, вместо присваивания errno, нужно вызывать внешнюю функцию.
void inside_dll_func() { ... ... set_errno_in_exe(ERROR_CODE); ... }