Здравствуйте Аноним, Вы писали:
AF>>Специально для таких случаев сделал функцию GetCurrentInstance (по аналогии с GetCurrentThread и GetCurrentProcess). Возвращает HINSTANCE модуля, из которого была вызвана эта функция.
А>Мне кажется, что во второй функции лучше использовать GetThreadContext. Получится переносимее.
Во-первых, в таком случае она перестанет решать поставленную задачу, а именно возвращает HINSTANCE модуля, из которого была вызвана эта функция. Вместо этого она будет возвращать HINSTANCE модуля в котором она сама находится, что тоже неплохо.
Во-вторых, структура CONTEXT сама по себе зависит от платформы, так что выигрыш в переносимости не очень большой.
Здравствуйте Alex Fedotov, Вы писали:
AF>Во-первых, в таком случае она перестанет решать поставленную задачу, а именно возвращает HINSTANCE модуля, из которого была вызвана эта функция. Вместо этого она будет возвращать HINSTANCE модуля в котором она сама находится, что тоже неплохо.
Да, про это я не подумал.
AF>Во-вторых, структура CONTEXT сама по себе зависит от платформы, так что выигрыш в переносимости не очень большой.
Здравствуйте SergH, Вы писали:
AF>>Во-первых, в таком случае она перестанет решать поставленную задачу, а именно возвращает HINSTANCE модуля, из которого была вызвана эта функция. Вместо этого она будет возвращать HINSTANCE модуля в котором она сама находится, что тоже неплохо.
SH>Да, про это я не подумал.
Кстати, о переносимости. Только что узнал, причем читая книгу Рихтера про .Net.
Оказывается, VC 7.0 поддерживат intrinsic-функцию с именем _ReturnAddress, которая возвращает адрес возврата из текущей функции. С ее помощью можно обойтись и без ассемблера.
Но самое интересное в том, что на VC 6.0 она тоже поддерживается (уж не знаю, начиная с какого SP), так что вот этот код без проблем компилируется и работает на моем VC 6.0 SP5 + Processor Pack.
Здравствуйте Alex Fedotov, Вы писали:
AF>>Специально для таких случаев сделал функцию GetCurrentInstance (по аналогии с GetCurrentThread и GetCurrentProcess). Возвращает HINSTANCE модуля, из которого была вызвана эта функция.
Здравствуйте Kaa, Вы писали:
Kaa>В каких случаях мой вариант не будет работать?
Вопрос снимается. Функция при загрузке dll в другой адрес имеет адрес относительно адреса, указанного при сборке dll, а не относительно того, в который dll была загружена. (Как мутно выразился )
Здравствуйте 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>Так что переносимость в пределах поддерживаемых MS платформ обеспечена (а для других задача не имеет смысла).
Мне понравилось. Попробовал. У меня на VC6 SP5 без Processor Pack скомпилялось без проблем. На моей W2K работает тоже без проблем. А вот на W98SE срабатывает _ASSERTE(mem.Type == MEM_IMAGE);. Можно ли это победить?
AF>>Так что переносимость в пределах поддерживаемых MS платформ обеспечена (а для других задача не имеет смысла).
P>Мне понравилось. Попробовал. У меня на VC6 SP5 без Processor Pack скомпилялось без проблем. На моей W2K работает тоже без проблем. А вот на W98SE срабатывает _ASSERTE(mem.Type == MEM_IMAGE);. Можно ли это победить?
AF>>>Так что переносимость в пределах поддерживаемых MS платформ обеспечена (а для других задача не имеет смысла).
P>>Мне понравилось. Попробовал. У меня на VC6 SP5 без Processor Pack скомпилялось без проблем. На моей W2K работает тоже без проблем. А вот на W98SE срабатывает _ASSERTE(mem.Type == MEM_IMAGE);. Можно ли это победить?
AF>А что там в поле Type оказалось?
Здравствуйте Alex Fedotov, Вы писали:
AF>Здравствуйте Polosaty, Вы писали:
AF>>>А что там в поле Type оказалось?
P>>MEM_PRIVATE
AF>Э... Ну если адрес правильный возвращается, просто убери этот ASSERT и все.
Я совсем убирать не стал, в релизе сам уберется. Сделал на всякий случай
Недавно встретил еще один любопытный подход. Выглядит он примерно так: есть некая dll, назовем ее lib1.dll. Для того, чтобы добраться до HINSTANCE, присутствует такая конструкция:
HINSTANCE hRes=LoadLibrary("Lib1.dll");
т.е. делается LoadLibrary самой себя. Как я понимаю, dll не может быть повторно загружена в адресное пространство процесса, т.е. данный вызов только возвращает HINSTANCE. Есть ли недостатки у такого подхода (не считая экзотики типа одноименных библиотек, загруженных из разных каталогов).
Здравствуйте, 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