Реализация отложенной загрузки библиотек на С++
От: Андрей Солодовников Россия http://alchemy-lab.com
Дата: 29.10.04 14:47
Оценка: 772 (23) +2
Статья:
Реализация отложенной загрузки библиотек на С++
Автор(ы): Андрей Солодовников
Дата: 20.03.2005
В данной статье описывается способ реализации отложенной загрузки динамических библиотек на С++ без использования механизма delayload, приведена реализация библиотеки отложенной загрузки и пример ее использования.



Авторы:
Андрей Солодовников

Аннотация:
В данной статье описывается способ реализации отложенной загрузки динамических библиотек на С++ без использования механизма delayload, приведена реализация библиотеки отложенной загрузки и пример ее использования.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Реализация отложенной загрузки библиотек на С++
От: rastoman  
Дата: 03.11.04 13:57
Оценка:
Здравствуйте, Андрей Солодовников, Вы писали:

ДЫК ОНА НЕ ВСЯ.
КОГДА ДОПИШИТЕ ТОГДА И ВЫКЛАДЫВАЙТЕ!!!

АС>Статья:



АС>Авторы:

АС> Андрей Солодовников

АС>Аннотация:

АС>В данной статье описывается способ реализации отложенной загрузки динамических библиотек на С++ без использования механизма delayload, приведена реализация библиотеки отложенной загрузки и пример ее использования.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
2 rsdn team
От: Рома Мик Россия http://romamik.com
Дата: 03.11.04 19:56
Оценка:
Здравствуйте, rastoman, Вы писали:

R>ДЫК ОНА НЕ ВСЯ.

R>КОГДА ДОПИШИТЕ ТОГДА И ВЫКЛАДЫВАЙТЕ!!!
Анонсы журнальных статей
Автор: Рома Мик
Дата: 02.11.04
Re: Реализация отложенной загрузки библиотек на С++
От: Andrew S Россия http://alchemy-lab.com
Дата: 25.03.05 16:41
Оценка:
Всем привет.
BTW, по адресу http://gzip.rsdn.ru/File/8583/delayimphlp.zip лежит немного обновленная версия исходников библиотеки. Пофикшен маленький баг с UNICODE и добавлена возможность пользовать функции без параметров. Насчет того, надо ли обновлять исходники, выложенные тут — я не знаю. В принципе, особой ценности внесенные изменения не несут, хотя. В общем, просто уведомляю, что есть более свежий вариант исходников — решать вам...
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: Реализация отложенной загрузки библиотек на С++
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 25.03.05 16:59
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>надо ли обновлять исходники, выложенные тут — я не знаю.


обновил
Re: Реализация отложенной загрузки библиотек на С++
От: Дед Пихто  
Дата: 29.03.05 12:01
Оценка:
Здравствуйте, Андрей Солодовников, Вы писали:

АС>Статья:

АС>Реализация отложенной загрузки библиотек на С++
Автор(ы): Андрей Солодовников
Дата: 20.03.2005
В данной статье описывается способ реализации отложенной загрузки динамических библиотек на С++ без использования механизма delayload, приведена реализация библиотеки отложенной загрузки и пример ее использования.



АС>Авторы:

АС> Андрей Солодовников

АС>Аннотация:

АС>В данной статье описывается способ реализации отложенной загрузки динамических библиотек на С++ без использования механизма delayload, приведена реализация библиотеки отложенной загрузки и пример ее использования.

Спасибо Андрею за отличную статью. А где бы еще почитать о шаблонах проектирования и реализации плагинов?
Re: Реализация отложенной загрузки библиотек на С++
От: raskolnikov  
Дата: 31.03.05 11:50
Оценка:
Nazvanie stat'i ne korrektnoe.
Code kishit MS-Specifichnymi Funkcijami.
MSVC++ != C++

Здравствуйте, Андрей Солодовников, Вы писали:

АС>Статья:

АС>Реализация отложенной загрузки библиотек на С++
Автор(ы): Андрей Солодовников
Дата: 20.03.2005
В данной статье описывается способ реализации отложенной загрузки динамических библиотек на С++ без использования механизма delayload, приведена реализация библиотеки отложенной загрузки и пример ее использования.



АС>Авторы:

АС> Андрей Солодовников

АС>Аннотация:

АС>В данной статье описывается способ реализации отложенной загрузки динамических библиотек на С++ без использования механизма delayload, приведена реализация библиотеки отложенной загрузки и пример ее использования.
Re[2]: Реализация отложенной загрузки библиотек на С++
От: Andrew S Россия http://alchemy-lab.com
Дата: 31.03.05 12:04
Оценка:
R>Nazvanie stat'i ne korrektnoe.
R>Code kishit MS-Specifichnymi Funkcijami.
R>MSVC++ != C++

А можно хотя бы один пример специфичной для компиляторов от m$ функции C++, используемой в статье? Платформенно-зависимые аспекты, ессно, тут включать в это не надо — функционал ориентирован на использование в среде win32.

PS Правилами сайта использование транслита крайне деприкейтед. В следующий раз для удобства читающих большая просьба — пользуйтесь услугами соотв. сайтов-переводчиков с транслита.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: Реализация отложенной загрузки библиотек на С++
От: raskolnikov  
Дата: 05.04.05 15:20
Оценка:
Здравствуйте, Andrew S, Вы писали:

R>>Nazvanie stat'i ne korrektnoe.

R>>Code kishit MS-Specifichnymi Funkcijami.
R>>MSVC++ != C++

AS>А можно хотя бы один пример специфичной для компиляторов от m$ функции C++,

Вот например: GetModuleHandle
Буду благодарен за аналогию в UNIX-е

AS>функционал ориентирован на использование в среде win32.


Как можно большая независимость от компилятора С++ (в пределах ANSI C++).
...
библиотека должна быть полностью функциональна на всех Visual C++ компиляторах


==

MSWord: Мултиплатформенное приложение, рапотает на Win98/W2K/XP
Re[4]: Реализация отложенной загрузки библиотек на С++
От: Andrew S Россия http://alchemy-lab.com
Дата: 05.04.05 15:58
Оценка:
AS>>А можно хотя бы один пример специфичной для компиляторов от m$ функции C++,

R>Вот например: GetModuleHandle

R>Буду благодарен за аналогию в UNIX-е

1. Где в статье хоть слово про мультиплатформенность? Там есть про соответствие библиотеки нормам анси С++.
2. Каким образом GetModuleHandle является спецификой m$ компилятора? Что, в Borland C++ или в комеау под win32 ее нет? Эта функция является спецификой среды, и тут никуда от этого не деться.
3. Проблемы портировать под Х не вижу. Написать соотв. стратегии. Или вы где-нибудь видели библиотеку, конечный код которой не вызывает системные функции? Счастливчик!

И еще раз повторюсь — библиотека в том виде, в котором изложена в статье, рассчитана на win32 изначально. И то, что она использует С++, четко отражено в названии статьи.
Ну и читать то, что пишет собеседник, тоже неплохо:
AS>Платформенно-зависимые аспекты, ессно, тут включать в это не надо — функционал ориентирован на использование в среде win32.

Если функция GetModuleHandle, по вашему мнению, не соответствует нормам ansi C++, то и любые подобные функции в unix тоже соответствовать не будут. более того, в С++ вообще нет понятия о мультипоточности — впрочем, никто полного соответствия и не обещал.

R>

R>Как можно большая независимость от компилятора С++ (в пределах ANSI C++).
R>...
R>библиотека должна быть полностью функциональна на всех Visual C++ компиляторах


R>==


R>MSWord: Мултиплатформенное приложение, рапотает на Win98/W2K/XP


Где в статье хоть слово про мультиплатформенность? Там есть про желательность соответствия кода библиотеки нормам анси С++.

В общем, все с вами понятно. Если есть что по делу сказать — говорите. А так... смысла продолжать полемику в этом русле не вижу. Удачи.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: Реализация отложенной загрузки библиотек на С++
От: Andrew S Россия http://alchemy-lab.com
Дата: 16.05.05 11:11
Оценка:
AS>>надо ли обновлять исходники, выложенные тут — я не знаю.

OE>обновил


Дико извиняюсь, но, похоже, опять можно обновить исходники к статье. Я таки сделал там нормальный интерфейс для функций без параметров, соотв. дополнительные макросы стали не нужны. Адрес прежний — http://www.rsdn.ru/File/8583/delayimphlp.zip ...
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Реализация отложенной загрузки библиотек на С++
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 16.05.05 11:38
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Дико извиняюсь, но, похоже, опять можно обновить исходники к статье. Я таки сделал там нормальный интерфейс для функций без параметров, соотв. дополнительные макросы стали не нужны. Адрес прежний — http://www.rsdn.ru/File/8583/delayimphlp.zip ...


ок, обновил
... << RSDN@Home 1.1.4 beta 7 rev. 451>>
Re[4]: Реализация отложенной загрузки библиотек на С++
От: 23W http://kyselgov.pp.ua/
Дата: 19.07.05 09:43
Оценка:
Здравствуйте, Andrew S:
В версии 1.1.1 при компиляции шаблона DL_DECLARE_FUN_THROW компилятором VС++ 7.1 выдаются два предупреждения С4702 и С4100. Как от них избавиться ?
Re[5]: Реализация отложенной загрузки библиотек на С++
От: Andrew S Россия http://alchemy-lab.com
Дата: 19.07.05 10:18
Оценка:
23W>Здравствуйте, Andrew S:
23W>В версии 1.1.1 при компиляции шаблона DL_DECLARE_FUN_THROW компилятором VС++ 7.1 выдаются два предупреждения С4702 и С4100. Как от них избавиться ?

Вариантов несколько (у меня 4100 не выдается, только 4702)...

1. Установить уровень W как 3-й. Ничего полезного, на мой взгляд, 4-й не добавит.
2. Запретить эти предупреждения явно до включения библиотеки импорта.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[5]: Реализация отложенной загрузки библиотек на С++
От: Аноним  
Дата: 15.09.05 11:32
Оценка:
R>>

R>>Как можно большая независимость от компилятора С++ (в пределах ANSI C++).
R>>...
R>>библиотека должна быть полностью функциональна на всех Visual C++ компиляторах


Отличная штука! Только жаль не работает на ICC 8.1:

...
.\DelayLoad/delayimphlp.h(571): error: identifier "P1v1" is undefined
.\DelayLoad/delayimphlp.h(571): error: identifier "P1v1" is undefined
detected during instantiation of class "delayload::CFunProxy1Impl<void>" at line 571
...

и так 300 раз
Re[6]: Реализация отложенной загрузки библиотек на С++
От: Andrew S Россия http://alchemy-lab.com
Дата: 15.09.05 12:20
Оценка:
А>...
А>.\DelayLoad/delayimphlp.h(571): error: identifier "P1v1" is undefined
А>.\DelayLoad/delayimphlp.h(571): error: identifier "P1v1" is undefined
А> detected during instantiation of class "delayload::CFunProxy1Impl<void>" at line 571
А>...

А>и так 300 раз


Судя по ошибке, проблема с препроцессором, и наверняка это макрос DL_REPEAT_PARAM_N. Вот только непонятно, что там такого, чего не понимает ICC...
Жаль, этого компилятора у меня нет, так что лично поправить не получится.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[6]: Реализация отложенной загрузки библиотек на С++
От: Andrew S Россия http://alchemy-lab.com
Дата: 25.09.05 22:13
Оценка: 21 (1) +1
R>>>

R>>>Как можно большая независимость от компилятора С++ (в пределах ANSI C++).
R>>>...
R>>>библиотека должна быть полностью функциональна на всех Visual C++ компиляторах


А>Отличная штука! Только жаль не работает на ICC 8.1:


А>...

А>.\DelayLoad/delayimphlp.h(571): error: identifier "P1v1" is undefined
А>.\DelayLoad/delayimphlp.h(571): error: identifier "P1v1" is undefined
А> detected during instantiation of class "delayload::CFunProxy1Impl<void>" at line 571
А>...

А>и так 300 раз


По адресу http://gzip.rsdn.ru/File/8583/delayimphlp.zip можно скачать обновление. Вместо предлаемых библиотекой макросов размножения параметров можно определением #define DL_USE_BOOST_PP перед включением заголовка библиотеки попросить ее использовать оные из буста.

2Odi$$ey — если можно, хорошо бы обновить исходники, которые идут к статье. Ссылка приведена выше. Спасибо.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Реализация отложенной загрузки библиотек на С++
От: Аноним  
Дата: 02.11.05 15:37
Оценка:
К сожалению, эту методику нельзя использовать в dll.

Вызов LoadLibrary/FreeLibrary в момент загрузки/выгрузки dll запрещен. А конструкторы и деструкторы в dll вызываются как раз в этот момент.

/Sergey
Re[2]: Реализация отложенной загрузки библиотек на С++
От: 23W http://kyselgov.pp.ua/
Дата: 02.11.05 15:54
Оценка:
Здравствуйте, Аноним, Вы писали:

А>К сожалению, эту методику нельзя использовать в dll.

А>Вызов LoadLibrary/FreeLibrary в момент загрузки/выгрузки dll запрещен. А конструкторы и деструкторы в dll вызываются как раз в этот момент.
А>/Sergey

Почему же вдруг нельзя ? Я использую широко эту библиотеку, в том числе и в dll. Дело в том, что непосредственно вызов LoadLibrary/FreeLibrary происходит не в момент загрузки твоего модуля (функиция dllmain), а в момент первого обращения к функции в "отложеннной" dll-ке, а это обычно происходит гораздо позже (при вызове экспортных функций вашего модуля).
Re[3]: Реализация отложенной загрузки библиотек на С++
От: Аноним  
Дата: 03.11.05 12:27
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Почему же вдруг нельзя ? Я использую широко эту библиотеку, в том числе и в dll. Дело в том, что непосредственно вызов LoadLibrary/FreeLibrary происходит не в момент загрузки твоего модуля (функиция dllmain), а в момент первого обращения к функции в "отложеннной" dll-ке, а это обычно происходит гораздо позже (при вызове экспортных функций вашего модуля).


А выгрузка происходит после вызова DllMain(PROCESS_DETTACH) (неявно используется atexit(<destructor>))
Т.е. получается вложеный вызов FreeLibrary.

Это может привести к серьезным проблемам, подробнее — в MSDN, секция Remarks в описании DllMain


The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, the entry-point function must not call the FreeLibrary function (or a function that calls FreeLibrary) during process termination, because this can result in a DLL being used after the system has executed its termination code.



//Sergey
Re[4]: Реализация отложенной загрузки библиотек на С++
От: Andrew S Россия http://alchemy-lab.com
Дата: 03.11.05 12:54
Оценка:
А>А выгрузка происходит после вызова DllMain(PROCESS_DETTACH) (неявно используется atexit(<destructor>))
А>Т.е. получается вложеный вызов FreeLibrary.

Для этого и есть CModule::IsLoaded и CModule::UnloadModule.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[5]: Реализация отложенной загрузки библиотек на С++
От: Аноним  
Дата: 15.01.08 07:03
Оценка:
Здравствуйте, Andrew S

У меня возник вопрос. Возможно я что-то неправильно поняла, но когда я использую вашу библиотеку, вызываю функцию из dll, которая возвращает значение типа int, то не получаю ничего кроме null. Что не так я делаю и как мне реализовать возможность обмена данными с моей dll?
Re[6]: Реализация отложенной загрузки библиотек на С++
От: Andrew S Россия http://alchemy-lab.com
Дата: 15.01.08 17:38
Оценка:
А>У меня возник вопрос. Возможно я что-то неправильно поняла, но когда я использую вашу библиотеку, вызываю функцию из dll, которая возвращает значение типа int, то не получаю ничего кроме null. Что не так я делаю и как мне реализовать возможность обмена данными с моей dll?

"Стучит где-то в машинном отделении"
Неплохо было бы пример кода. Ну и библиотеку посоветую взять по этой ссылке — она там иногда обновляется, в отличие от той, что вместе со статьей

PS
Да, к слову о формулировке вопроса. Функция, возвращающая int, значение null возвращать ну никак не может. 0 — другое дело.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[7]: Реализация отложенной загрузки библиотек на С++
От: VirLena  
Дата: 16.01.08 13:51
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>"Стучит где-то в машинном отделении"

AS>Неплохо было бы пример кода. Ну и библиотеку посоветую взять по этой ссылке — она там иногда обновляется, в отличие от той, что вместе со статьей

В коде особо не мудрствовала, просто захотелось проверить использование вашей библиотеки, ну например

Функция в Dll


int SampleFunction(bool tmp)
{
    if(tmp){
        ::MessageBox(0,"Флаг получил значение true","Сообщение о загрузке Dll",MB_OK);
        return 1;
    }
    else{
        ::MessageBox(0,"Флаг получил значение false","Сообщение о загрузке Dll",MB_OK);
        return 2;
    }
}


И вызов из основного приложения


DL_USE_MODULE_BEGIN(loaddll, "DelayLoadDll.dll")
    DL_DECLARE_FUN(SampleFunction, int, (bool))
DL_USE_MODULE_END()

void CNewProgectDllDlg::OnDelay() 
{
    UpdateData(true);
    int tmp = 0;
    if (m_flag.GetCurSel() == 0)
        tmp = loaddll::SampleFunction(true);
    if (m_flag.GetCurSel() == 1)
        tmp = loaddll::SampleFunction(false);
    m_tmp.Format("%3i",tmp);
    UpdateData(false);
    
}


Все прекрасно собирается, но увы не с тем результатом....

AS>PS

AS>Да, к слову о формулировке вопроса. Функция, возвращающая int, значение null возвращать ну никак не может. 0 — другое дело.

Извените, просто небольшой сленг.
Re[8]: Реализация отложенной загрузки библиотек на С++
От: VirLena  
Дата: 16.01.08 13:57
Оценка:
Кстати, попробывала подгрузить свою dll в ваш пример в консольки, dll грузит, но опять же от функций ничего не приходит, наверняка я что-то недопонимаю , спасибо если поможете разобраться
Re[8]: Реализация отложенной загрузки библиотек на С++
От: Andrew S Россия http://alchemy-lab.com
Дата: 16.01.08 17:57
Оценка:
VL>Функция в Dll

[skipped]

Соглашение по вызовам — WINAPI. Надо указывать явно.
Ну а то, что не возвращает — на что людям дан дебаггер?
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[9]: Реализация отложенной загрузки библиотек на С++
От: Andrew S Россия http://alchemy-lab.com
Дата: 17.01.08 18:33
Оценка:
VL>Кстати, попробывала подгрузить свою dll в ваш пример в консольки, dll грузит, но опять же от функций ничего не приходит, наверняка я что-то недопонимаю , спасибо если поможете разобраться

Вдогонку — посмотрите depends'ом экспортируемые из dll функции. Наверняка у вас манглинг, поскольку нет def файла.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Вопрос по количеству параметров
От: Obukhov Россия  
Дата: 11.02.08 15:15
Оценка:
Добрый день,
Случилось так, что мне нужно импортировать из DLL функцию с 21-м параметром + еще возвращаемое значение.


сейчас компилятор (VS 2005 SP1) выдает следующее:

.cpp(35) : error C2039: 'CFunProxy__stdcall17' : is not a member of 'delayload'
.cpp(35) : error C2144: syntax error : 'char' should be preceded by ')'
.cpp(35) : error C3861: 'CFunProxy__stdcall17': identifier not found
.cpp(35) : error C2144: syntax error : 'char' should be preceded by ')'
.cpp(35) : error C3861: 'DL_SEQ_ENUM_DL_N_DL_SEQ_SIZE_17': identifier not found
.cpp(35) : error C2059: syntax error : ')'
.cpp(35) : error C2947: expecting '>' to terminate template-argument-list, found '>'
.cpp(35) : error C2976: 'delayload::CDynFunction' : too few template arguments


Что нужно дописать в программе, что бы можно было импортировать такие функции ?
Re[2]: Ну в общем разобрался сам...
От: Obukhov Россия  
Дата: 11.02.08 15:38
Оценка:
Все довольно тривиально ...
... << RSDN@Home 1.2.0 alpha rev. 774>>
Re[3]: Ну в общем разобрался сам...
От: Andrew S Россия http://alchemy-lab.com
Дата: 11.02.08 17:41
Оценка:
O>Все довольно тривиально ...

Рекомендую брать библиотеку отсюда: http://files.rsdn.ru/8583/delayimphlp.zip

Там оно изредка обновляется, да и в целом — для Вашей задачи никаких обновлений не требуется, просто определить макрос, дабы использовался буст (DL_USE_BOOST_PP).

Кроме того, есть мысль, что функция с числом параметров более 4-х есть пример плохого проектирования. 21 параметр — имхо, жесть.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Ну в общем разобрался сам...
От: Obukhov Россия  
Дата: 11.02.08 19:39
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Рекомендую брать библиотеку отсюда: http://files.rsdn.ru/8583/delayimphlp.zip

Так я оттуда и брал!

AS>Там оно изредка обновляется, да и в целом — для Вашей задачи никаких обновлений не требуется, просто определить макрос, дабы использовался буст (DL_USE_BOOST_PP).

Я бы рад, но проект небольшой и пристегнув к нему boost получится этакий диплодок
Хотя может и правда стоит

AS>Кроме того, есть мысль, что функция с числом параметров более 4-х есть пример плохого проектирования. 21 параметр — имхо, жесть.

А кто говорит что хорошее проектирование. Но делать нечего т.к. библиотечка сторонняя и сделать с ней я ничего не могу
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Ну в общем разобрался сам...
От: Andrew S Россия http://alchemy-lab.com
Дата: 11.02.08 21:59
Оценка:
AS>>Рекомендую брать библиотеку отсюда: http://files.rsdn.ru/8583/delayimphlp.zip
O>Так я оттуда и брал!

Ну, значит, все в порядке

AS>>Там оно изредка обновляется, да и в целом — для Вашей задачи никаких обновлений не требуется, просто определить макрос, дабы использовался буст (DL_USE_BOOST_PP).

O>Я бы рад, но проект небольшой и пристегнув к нему boost получится этакий диплодок
O>Хотя может и правда стоит

Можно выдрать из буста::препроцессор только нужные куски — их там немного (последовательности и итерации по ним + несколько мелких кейсов).
Впрочем, тут дело ваше — главное, чтобы в результате все работало.

AS>>Кроме того, есть мысль, что функция с числом параметров более 4-х есть пример плохого проектирования. 21 параметр — имхо, жесть.

O>А кто говорит что хорошее проектирование. Но делать нечего т.к. библиотечка сторонняя и сделать с ней я ничего не могу

Ну, при желании сделать можно. Например, прокси-библиотеку, которая линкует указанного монстра статически и заворачивает его апи в более культурный, а остальное просто "пробрасывает". Ну да это перебор, наверное. В общем, удачи.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.