FAQ:WinAPI VCPP:значение переменной для вызывающего процесса/потока из своей собственной DLL — различия между версиями

Материал из Весельчак У
Перейти к: навигация, поиск
(Новая: === Каким образом можно установить значение переменной для вызывающего процесса/потока из своей собст...)
 
Строка 1: Строка 1:
=== Каким образом можно установить значение переменной для вызывающего процесса/потока из своей собственной DLL? Проблема заключается в том, что несмотря на то, что все линкуется нормально, значение переменной процесса не изменяется, когда я его устанавливаю вручную в библиотеке. ===
+
=== Каким образом можно установить значение переменной для вызывающего процесса/потока из своей собственной DLL? Проблема заключается в том, что несмотря на то, что все линкуется нормально, значение переменной процесса не изменяется, когда я его устанавливаю вручную в библиотеке. ===
  
 
Проблема вызвана тем, что каждая влинкованная libc (одна линкуется в исполняемый файл, ещё одна в dll) содержит свою копию переменной.  
 
Проблема вызвана тем, что каждая влинкованная libc (одна линкуется в исполняемый файл, ещё одна в dll) содержит свою копию переменной.  
Строка 5: Строка 5:
 
1) Можно воспользоваться динамически подгружаемой библиотекой С runtime. Для этого приложение и dll надо компилировать с ключом /MD (или MDd для отладки). В таком случае переменная будет общей для приложения и dll.  
 
1) Можно воспользоваться динамически подгружаемой библиотекой С runtime. Для этого приложение и dll надо компилировать с ключом /MD (или MDd для отладки). В таком случае переменная будет общей для приложения и dll.  
  
2) Можно в основном модуле программы (тот, который станет .exe) сделать "дырку" (backdoor), через которую присваивать переменной (int errno) значение: <br>&lt;pre&gt;__declspec(dllexport) void set_errno(int code)<br>{<br>errno = code;<br>}<br>&lt;/pre&gt;<br>В dll при подключении к процессу надо извлечь из модуля программы указатель на эту функцию. <br>&lt;pre&gt; typedef void (*SETINT)(int);<br>SETINT g_set_errno=0;<br>void set_errno_in_exe(int code)<br>{<br>if(g_set_errno) g_set_errno(code);<br>}<br><br>BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )<br>{<br>HANDLE hModule; // Handle to the main module<br>if(fdwReason == DLL_PROCESS_ATTACH )<br>{<br>hModule = GetModuleHandle(NULL);<br>if (hModule == NULL) return FALSE;<br>g_set_errno = (SETINT) GetProcAddress(hModule, "set_errno");<br>}<br>return TRUE;<br>}<br>&lt;/pre&gt;<br>В нужном месте в dll вместо присваивания errno нужно вызывать внешнюю функцию <br>&lt;pre&gt;void inside_dll_func()<br>{<br>...<br>...<br>set_errno_in_exe(ERROR_CODE);<br>...<br>}<br>&lt;/pre&gt;
+
2) Можно в основном модуле программы (тот, который станет .exe) сделать "дырку" (backdoor), через которую присваивать переменной (int errno) значение: <br>&lt;pre&gt;
 +
 
 +
__declspec(dllexport) void set_errno(int code)<br>{<br>errno = code;<br>}<br>&lt;/pre&gt;<br>В dll при подключении к процессу надо извлечь из модуля программы указатель на эту функцию. <br>&lt;pre&gt; typedef void (*SETINT)(int);<br>SETINT g_set_errno=0;<br>void set_errno_in_exe(int code)<br>{<br>if(g_set_errno) g_set_errno(code);<br>}<br><br>BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )<br>{<br>HANDLE hModule; // Handle to the main module<br>if(fdwReason == DLL_PROCESS_ATTACH )<br>{<br>hModule = GetModuleHandle(NULL);<br>if (hModule == NULL) return FALSE;<br>g_set_errno = (SETINT) GetProcAddress(hModule, "set_errno");<br>}<br>return TRUE;<br>}<br>&lt;/pre&gt;<br>В нужном месте в dll вместо присваивания errno нужно вызывать внешнюю функцию <br>&lt;pre&gt;void inside_dll_func()<br>{<br>...<br>...<br>set_errno_in_exe(ERROR_CODE);<br>...<br>}<br>&lt;/pre&gt;

Версия 20:11, 3 октября 2008

Каким образом можно установить значение переменной для вызывающего процесса/потока из своей собственной DLL? Проблема заключается в том, что несмотря на то, что все линкуется нормально, значение переменной процесса не изменяется, когда я его устанавливаю вручную в библиотеке.

Проблема вызвана тем, что каждая влинкованная libc (одна линкуется в исполняемый файл, ещё одна в dll) содержит свою копию переменной.

1) Можно воспользоваться динамически подгружаемой библиотекой С runtime. Для этого приложение и dll надо компилировать с ключом /MD (или MDd для отладки). В таком случае переменная будет общей для приложения и dll.

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>