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

Материал из Весельчак У
Перейти к: навигация, поиск

Каким образом можно установить значение переменной для вызывающего процесса/потока из своей собственной 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);
	...
}