Re[3]: HMODULE в DLL
От: SergH Россия  
Дата: 24.02.02 17:16
Оценка:
Здравствуйте Аноним, Вы писали:

Блин. Опять забыл подписаться.
Делай что должно, и будь что будет
Re[3]: HMODULE в DLL
От: Alex Fedotov США  
Дата: 24.02.02 17:22
Оценка:
Здравствуйте Аноним, Вы писали:

AF>>Специально для таких случаев сделал функцию GetCurrentInstance (по аналогии с GetCurrentThread и GetCurrentProcess). Возвращает HINSTANCE модуля, из которого была вызвана эта функция.


А>Мне кажется, что во второй функции лучше использовать GetThreadContext. Получится переносимее.


Во-первых, в таком случае она перестанет решать поставленную задачу, а именно возвращает HINSTANCE модуля, из которого была вызвана эта функция. Вместо этого она будет возвращать HINSTANCE модуля в котором она сама находится, что тоже неплохо.

Во-вторых, структура CONTEXT сама по себе зависит от платформы, так что выигрыш в переносимости не очень большой.
-- Alex Fedotov
Re[4]: HMODULE в DLL
От: SergH Россия  
Дата: 24.02.02 17:41
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

AF>Во-первых, в таком случае она перестанет решать поставленную задачу, а именно возвращает HINSTANCE модуля, из которого была вызвана эта функция. Вместо этого она будет возвращать HINSTANCE модуля в котором она сама находится, что тоже неплохо.


Да, про это я не подумал.

AF>Во-вторых, структура CONTEXT сама по себе зависит от платформы, так что выигрыш в переносимости не очень большой.
Делай что должно, и будь что будет
Re[5]: HMODULE в DLL
От: Alex Fedotov США  
Дата: 24.02.02 22:04
Оценка: 87 (10)
Здравствуйте SergH, Вы писали:

AF>>Во-первых, в таком случае она перестанет решать поставленную задачу, а именно возвращает HINSTANCE модуля, из которого была вызвана эта функция. Вместо этого она будет возвращать HINSTANCE модуля в котором она сама находится, что тоже неплохо.


SH>Да, про это я не подумал.


Кстати, о переносимости. Только что узнал, причем читая книгу Рихтера про .Net.

Оказывается, VC 7.0 поддерживат intrinsic-функцию с именем _ReturnAddress, которая возвращает адрес возврата из текущей функции. С ее помощью можно обойтись и без ассемблера.

Но самое интересное в том, что на VC 6.0 она тоже поддерживается (уж не знаю, начиная с какого SP), так что вот этот код без проблем компилируется и работает на моем VC 6.0 SP5 + Processor Pack.

extern "C" void * _ReturnAddress();
#pragma intrinsic(_ReturnAddress)

HINSTANCE GetCurrentInstance()
{
    MEMORY_BASIC_INFORMATION mem;
    if (VirtualQuery(_ReturnAddress(), &mem, sizeof(mem)))
    {
        _ASSERTE(mem.Type == MEM_IMAGE);
        _ASSERTE(mem.AllocationBase != NULL);
        return (HINSTANCE)mem.AllocationBase;
    }
    return NULL;
}


Так что переносимость в пределах поддерживаемых MS платформ обеспечена (а для других задача не имеет смысла).
-- Alex Fedotov
Re[3]: HMODULE в DLL
От: Kaa Украина http://blog.meta.ua/users/kaa/
Дата: 25.02.02 15:31
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

AF>>Специально для таких случаев сделал функцию GetCurrentInstance (по аналогии с GetCurrentThread и GetCurrentProcess). Возвращает HINSTANCE модуля, из которого была вызвана эта функция.


А почему нельзя написать просто так:
HINSTANCE GetInstance()
{
  MEMORY_BASIC_INFORMATION mbi;
  if ( VirtualQuery( &GetInstance, &mbi, sizeof(mbi) ) )
  {
    _ASSERTE(mem.Type == MEM_IMAGE);
    _ASSERTE(mem.AllocationBase != NULL);
    return (HMODULE)mbi.AllocationBase;
  } 
  return NULL;
};
? Ведь GetInstance сам является указателем внутри модуля (code pointer), правильно? Тогда и платформная независимость появляется.

В чем соль той ассемблерной вставки? В каких случаях мой вариант не будет работать? Я прогнал его на одной конкретной машине под Win2k. Пашет.

С уважением
Алексей Кирдин
Re[4]: Вопрос снимается
От: Kaa Украина http://blog.meta.ua/users/kaa/
Дата: 25.02.02 15:51
Оценка: +1
Здравствуйте Kaa, Вы писали:

Kaa>В каких случаях мой вариант не будет работать?


Вопрос снимается. Функция при загрузке dll в другой адрес имеет адрес относительно адреса, указанного при сборке dll, а не относительно того, в который dll была загружена. (Как мутно выразился )

С уважением
Алексей Кирдин
Re[6]: HMODULE в DLL
От: Polosaty Беларусь  
Дата: 26.02.02 12:26
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

AF>Здравствуйте SergH, Вы писали:


AF>>>Во-первых, в таком случае она перестанет решать поставленную задачу, а именно возвращает HINSTANCE модуля, из которого была вызвана эта функция. Вместо этого она будет возвращать HINSTANCE модуля в котором она сама находится, что тоже неплохо.


SH>>Да, про это я не подумал.


AF>Кстати, о переносимости. Только что узнал, причем читая книгу Рихтера про .Net.


AF>Оказывается, VC 7.0 поддерживат intrinsic-функцию с именем _ReturnAddress, которая возвращает адрес возврата из текущей функции. С ее помощью можно обойтись и без ассемблера.


AF>Но самое интересное в том, что на VC 6.0 она тоже поддерживается (уж не знаю, начиная с какого SP), так что вот этот код без проблем компилируется и работает на моем VC 6.0 SP5 + Processor Pack.


AF>
AF>extern "C" void * _ReturnAddress();
AF>#pragma intrinsic(_ReturnAddress)

AF>HINSTANCE GetCurrentInstance()
AF>{
AF>    MEMORY_BASIC_INFORMATION mem;
AF>    if (VirtualQuery(_ReturnAddress(), &mem, sizeof(mem)))
AF>    {
AF>        _ASSERTE(mem.Type == MEM_IMAGE);
AF>        _ASSERTE(mem.AllocationBase != NULL);
AF>        return (HINSTANCE)mem.AllocationBase;
AF>    }
AF>    return NULL;
AF>}
AF>


AF>Так что переносимость в пределах поддерживаемых MS платформ обеспечена (а для других задача не имеет смысла).


Мне понравилось. Попробовал. У меня на VC6 SP5 без Processor Pack скомпилялось без проблем. На моей W2K работает тоже без проблем. А вот на W98SE срабатывает _ASSERTE(mem.Type == MEM_IMAGE);. Можно ли это победить?
Re[7]: HMODULE в DLL
От: Alex Fedotov США  
Дата: 26.02.02 18:29
Оценка:
Здравствуйте Polosaty, Вы писали:

AF>>
AF>>extern "C" void * _ReturnAddress();
AF>>#pragma intrinsic(_ReturnAddress)

AF>>HINSTANCE GetCurrentInstance()
AF>>{
AF>>    MEMORY_BASIC_INFORMATION mem;
AF>>    if (VirtualQuery(_ReturnAddress(), &mem, sizeof(mem)))
AF>>    {
AF>>        _ASSERTE(mem.Type == MEM_IMAGE);
AF>>        _ASSERTE(mem.AllocationBase != NULL);
AF>>        return (HINSTANCE)mem.AllocationBase;
AF>>    }
AF>>    return NULL;
AF>>}
AF>>


AF>>Так что переносимость в пределах поддерживаемых MS платформ обеспечена (а для других задача не имеет смысла).


P>Мне понравилось. Попробовал. У меня на VC6 SP5 без Processor Pack скомпилялось без проблем. На моей W2K работает тоже без проблем. А вот на W98SE срабатывает _ASSERTE(mem.Type == MEM_IMAGE);. Можно ли это победить?


А что там в поле Type оказалось?
-- Alex Fedotov
Re[8]: HMODULE в DLL
От: Polosaty Беларусь  
Дата: 26.02.02 18:55
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

AF>Здравствуйте Polosaty, Вы писали:


AF>>>
AF>>>extern "C" void * _ReturnAddress();
AF>>>#pragma intrinsic(_ReturnAddress)

AF>>>HINSTANCE GetCurrentInstance()
AF>>>{
AF>>>    MEMORY_BASIC_INFORMATION mem;
AF>>>    if (VirtualQuery(_ReturnAddress(), &mem, sizeof(mem)))
AF>>>    {
AF>>>        _ASSERTE(mem.Type == MEM_IMAGE);
AF>>>        _ASSERTE(mem.AllocationBase != NULL);
AF>>>        return (HINSTANCE)mem.AllocationBase;
AF>>>    }
AF>>>    return NULL;
AF>>>}
AF>>>


AF>>>Так что переносимость в пределах поддерживаемых MS платформ обеспечена (а для других задача не имеет смысла).


P>>Мне понравилось. Попробовал. У меня на VC6 SP5 без Processor Pack скомпилялось без проблем. На моей W2K работает тоже без проблем. А вот на W98SE срабатывает _ASSERTE(mem.Type == MEM_IMAGE);. Можно ли это победить?


AF>А что там в поле Type оказалось?


MEM_PRIVATE
Re[9]: HMODULE в DLL
От: Alex Fedotov США  
Дата: 26.02.02 19:20
Оценка:
Здравствуйте Polosaty, Вы писали:

AF>>А что там в поле Type оказалось?


P>MEM_PRIVATE


Э... Ну если адрес правильный возвращается, просто убери этот ASSERT и все.
-- Alex Fedotov
Re[10]: HMODULE в DLL
От: Polosaty Беларусь  
Дата: 26.02.02 19:29
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

AF>Здравствуйте Polosaty, Вы писали:


AF>>>А что там в поле Type оказалось?


P>>MEM_PRIVATE


AF>Э... Ну если адрес правильный возвращается, просто убери этот ASSERT и все.


Я совсем убирать не стал, в релизе сам уберется. Сделал на всякий случай
_ASSERTE(mem.Type == MEM_IMAGE || mem.Type == MEM_PRIVATE);

Работает. По крайней мере, по получаемому Instance до ресурса в DLL добирается.
Спасибо.
Re: HMODULE в DLL
От: Polosaty Беларусь  
Дата: 24.11.03 00:01
Оценка:
Недавно встретил еще один любопытный подход. Выглядит он примерно так: есть некая dll, назовем ее lib1.dll. Для того, чтобы добраться до HINSTANCE, присутствует такая конструкция:

HINSTANCE hRes=LoadLibrary("Lib1.dll");


т.е. делается LoadLibrary самой себя. Как я понимаю, dll не может быть повторно загружена в адресное пространство процесса, т.е. данный вызов только возвращает HINSTANCE. Есть ли недостатки у такого подхода (не считая экзотики типа одноименных библиотек, загруженных из разных каталогов).
Re[2]: HMODULE в DLL
От: SergeMukhin Россия  
Дата: 24.11.03 05:52
Оценка:
Здравствуйте, Polosaty, Вы писали:

P>Недавно встретил еще один любопытный подход. Выглядит он примерно так: есть некая dll, назовем ее lib1.dll. Для того, чтобы добраться до HINSTANCE, присутствует такая конструкция:


P>
P>HINSTANCE hRes=LoadLibrary("Lib1.dll");
P>


P>т.е. делается LoadLibrary самой себя. Как я понимаю, dll не может быть повторно загружена в адресное пространство процесса, т.е. данный вызов только возвращает HINSTANCE. Есть ли недостатки у такого подхода (не считая экзотики типа одноименных библиотек, загруженных из разных каталогов).


а DllMain будет отрабатывать второй раз? если так, то лучше LoadLibraryEx c LOAD_LIBRARY_AS_DATAFILE
... << RSDN@Home 1.1.0 stable >>
---
С уважением,
Сергей Мухин
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.