FAQ:WinAPI VCPP:значение переменной для вызывающего процесса/потока из своей собственной DLL — различия между версиями
Материал из Весельчак У
Строка 8: | Строка 8: | ||
<pre>__declspec(dllexport) void set_errno(int code) | <pre>__declspec(dllexport) void set_errno(int code) | ||
{ | { | ||
− | errno = code; | + | errno = code; |
} | } | ||
</pre> | </pre> | ||
В dll при подключении к процессу надо извлечь из модуля программы указатель на эту функцию. | В dll при подключении к процессу надо извлечь из модуля программы указатель на эту функцию. | ||
− | <pre>typedef void (*SETINT)(int); | + | <pre> typedef void (*SETINT)(int); |
− | SETINT g_set_errno=0; | + | SETINT g_set_errno=0; |
− | void set_errno_in_exe(int code) | + | void set_errno_in_exe(int code) |
− | { | + | { |
− | if(g_set_errno) g_set_errno(code); | + | if(g_set_errno) g_set_errno(code); |
− | } | + | } |
− | + | ||
− | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) | + | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) |
− | { | + | { |
− | HANDLE hModule; // Handle to the main module | + | HANDLE hModule; // Handle to the main module |
− | if(fdwReason == DLL_PROCESS_ATTACH ) | + | if(fdwReason == DLL_PROCESS_ATTACH ) |
− | { | + | { |
− | hModule = GetModuleHandle(NULL); | + | hModule = GetModuleHandle(NULL); |
− | if (hModule == NULL) return FALSE; | + | if (hModule == NULL) return FALSE; |
− | g_set_errno = (SETINT) GetProcAddress(hModule, "set_errno"); | + | g_set_errno = (SETINT) GetProcAddress(hModule, "set_errno"); |
− | } | + | } |
− | return TRUE; | + | return TRUE; |
− | } </pre> | + | } |
+ | </pre> | ||
В нужном месте в dll вместо присваивания errno нужно вызывать внешнюю функцию | В нужном месте в dll вместо присваивания errno нужно вызывать внешнюю функцию | ||
<pre>void inside_dll_func() | <pre>void inside_dll_func() | ||
{ | { | ||
− | ... | + | ... |
− | ... | + | ... |
− | set_errno_in_exe(ERROR_CODE); | + | set_errno_in_exe(ERROR_CODE); |
− | ... | + | ... |
− | } | + | } |
+ | </pre> |
Версия 23:04, 3 октября 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); ... }