Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: msvc: dll и errno  (Прочитано 7175 раз)
0 Пользователей и 7 Гостей смотрят эту тему.
darkelf
Молодой специалист

nl
Offline Offline

« : 21-05-2004 08:30 » new

Добрый день.
Подскажите пожалуйста, каким образом, можно установить значение errno для вызывающего процесса/потока из своей собственной *.dll.
Проблема заключается в том, что несмотря на то, что все линкуется нормально, значение переменной errno, несмотря на то, что я его устанавливаю вручную в библиотеке, в процессе не изменяется.
Возможно для этого нужны какие-либо особые ключи компилятора?
Спасибо за ответ.
Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 21-05-2004 11:17 » 

darkelf,

в основном модуле программы (тот, который станет .exe) надо сделать дырку (backdoor):
Код:
__declspec(dllexport) void set_errno(int code) {
    errno = code;
}

В dll при подключении к процессу надо извлечь из модуля программы указатель на эту функцию.

Код:
typedef void (*SETINT)(int);

SETINT g_set_errno = NULL;
void set_errno_in_exe(int code) {
    if (g_set_errno != NULL) 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() {
    // bla-bla-bla
    set_errno_in_exe(ERROR_CODE);
    // foo-foo
}

Проблема вызвана тем, что каждая влинкованная libc (одна линкуется в  исполняемый файл, ещё одна в dll) содержит свою копию errno.  Поэтому приходится пробивать дырку в адресное пространство исполняемого файла чтобы установить errno для него.
« Последнее редактирование: 25-11-2007 21:39 от Алексей1153++ » Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 21-05-2004 13:06 » 

Второй способ -- воспользоваться динамически подгружаемой библиотекой С runtime, MSVCRT.

Для этого приложение и dll надо компилировать с ключиком /MD (или MDd для отладки).  В таком случае errno будет общим для приложения и dll.  Приём из предыдущего постинга тоже будет работать.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
darkelf
Молодой специалист

nl
Offline Offline

« Ответ #3 : 21-05-2004 16:09 » 

Второй способ лучше, еще раз большое спасибо.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines