FAQ:WinAPI VCPP:значение переменной для вызывающего процесса/потока из своей собственной DLL — различия между версиями
Материал из Весельчак У
| Строка 5: | Строка 5: | ||
1) Можно воспользоваться динамически подгружаемой библиотекой С runtime. Для этого приложение и dll надо компилировать с ключом /MD (или MDd для отладки). В таком случае переменная будет общей для приложения и dll. | 1) Можно воспользоваться динамически подгружаемой библиотекой С runtime. Для этого приложение и dll надо компилировать с ключом /MD (или MDd для отладки). В таком случае переменная будет общей для приложения и dll. | ||
| − | 2) Можно в основном модуле программы (тот, который станет .exe) сделать "дырку" (backdoor), через которую присваивать переменной (int errno) значение: < | + | 2) Можно в основном модуле программы (тот, который станет .exe) сделать "дырку" (backdoor), через которую присваивать переменной (int errno) значение: |
| + | <pre> __declspec(dllexport) void set_errno(int code) | ||
| + | { | ||
| + | errno = code; | ||
| + | } | ||
| + | </pre> | ||
| + | В dll при подключении к процессу надо извлечь из модуля программы указатель на эту функцию. | ||
| + | <pre>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; | ||
| + | } </pre> | ||
| + | В нужном месте в dll вместо присваивания errno нужно вызывать внешнюю функцию | ||
| + | <pre>void inside_dll_func() | ||
| + | { | ||
| + | ... | ||
| + | ... | ||
| + | set_errno_in_exe(ERROR_CODE); | ||
| + | ... | ||
| + | } </pre> | ||
Версия 20:16, 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);
...
}