Динамическая подгрузка RTTI компонентов-библиотек
Привет всем !
Скачал потестировать FastScript, и сразу озадачился вот по какому поводу!
Есть набор компонентов Scripter Studio От TMS Software - по реализации очень похож на Fast Script. Там из обычных pas модулей с компонентами с помощью программы импортера (или вручную - но о-очень долго ) формируются файлы-обертки с реализацией класса TatLibrary - который содержит реализацию методов и свойств компонентов.
Файл обертку можно указать в uses разделе Delphi иодуля и вызвав Scripter.AddLibrary(TatSomeLibrary) Подключить ее к компоненту-скриптеру.
Мне не хотелось увеличивать объем исполняемого файла, включая в uses все модули-обертки, которые могут и не понадобиться, и я поступил следующим образом - подключал библиотеки в Run-Time если они были необходимы.
Создавал DLL, из которой экспортировалась функция, принимающая как Var-параметр объект скриптера, и добавляющая к нему библиотеку. Для каждого модуля своя DLL - stdctrls.dll, extctrls.dll и т.д.
А есть ли в Fast Script возможность также организовать динамическое подключение только нужных компонент. Чтобы не подключать прям в дизайн тайме все RTTI компоненты ???
Кстати, разработчики !!
Вы Молодцы - TMS'овцы никак не могут (или не хотят ) реализовать функциональность USES в своих скриптах !! И быстрых исправлений от них фиг добъешься !
Так держать !
Скачал потестировать FastScript, и сразу озадачился вот по какому поводу!
Есть набор компонентов Scripter Studio От TMS Software - по реализации очень похож на Fast Script. Там из обычных pas модулей с компонентами с помощью программы импортера (или вручную - но о-очень долго ) формируются файлы-обертки с реализацией класса TatLibrary - который содержит реализацию методов и свойств компонентов.
Файл обертку можно указать в uses разделе Delphi иодуля и вызвав Scripter.AddLibrary(TatSomeLibrary) Подключить ее к компоненту-скриптеру.
Мне не хотелось увеличивать объем исполняемого файла, включая в uses все модули-обертки, которые могут и не понадобиться, и я поступил следующим образом - подключал библиотеки в Run-Time если они были необходимы.
Создавал DLL, из которой экспортировалась функция, принимающая как Var-параметр объект скриптера, и добавляющая к нему библиотеку. Для каждого модуля своя DLL - stdctrls.dll, extctrls.dll и т.д.
А есть ли в Fast Script возможность также организовать динамическое подключение только нужных компонент. Чтобы не подключать прям в дизайн тайме все RTTI компоненты ???
Кстати, разработчики !!
Вы Молодцы - TMS'овцы никак не могут (или не хотят ) реализовать функциональность USES в своих скриптах !! И быстрых исправлений от них фиг добъешься !
Так держать !
Комментарии
А смысл, все равно ведь все библиотеки за собой таскать...
Сделать, конечно, можно (передавать в экспортируемую ф-ю fsGlobalUnit и добавлять в него нужные вещи). Не пробовал, но по идее должно работать.
Сейчас тут скажут, что хотя uses и есть, но работает криво, и будут правы
Да сказать-то скажут, но лиха беда начало !! Я, кстати, уже почитал по поводу нападок на реализацию USES !
А по поводу передачи в функцию fsGlobalUnit - это точно, вчера видимо тормозил и невнимательно поглядел на реализацию модулей fs_xxxxRTTI . Сейчас буду пробовать и если все ок, напишу в этом топике.
Библиотеки таскать-то придется, но во первых у меня там идет сборка с пакетами и DLL-ки получаются по 6-25 кб, а во вторых грузятся-то не все, а только нужные, а мне как раз и нужно было не просто избавиться от лишнего веса "exe", а скорее от загрузки в память ненужного груза компонентов, которые не будут использоваться в скрипте.
Сейчас если получится у меня то же, что и с компонентами от TMS - попробую написать парсер-импортер для автоматической генерации fs_xxxxxRTTI модулей. А то руками что-то сильно напрягаюсь такие вещи делать !
Спасибо за ответ !! Удачи !!
Нет у разработчиков в планах добавить компоненту TfsScript какую-нибудь функцию типа AddLibrary, которая в качестве параметра принимала бы абстрактный класс TFunction, а все TFunction в модулях fs_xxxxxxRTTI наследовать от абстрактного класса ?
ИМХО удобно было бы !
С уважением и почтением к столь мудрым разработчикам !!
Передавал !!
Отрабатывает и основной EXE и DLL, и внутри DLL с переданным экземпляром fsScript проходит все ок : классы, константы и все остальное добавляются !!
Конструктор в файле fs_ixxxxrtti исправил так чтобы работал не c fsGlobalUnit из подключенного модуля, а с переданным экземпляром. Отключил разделы initialization и finalization, Functions создаю вручную.
Объявление класса TFunctions и переменную Functions вынес в interface, чтоб видно их было !!
Вот такой процедуркой работаю в DLL с переданным из основной программы fsGlobalUnit'ом :
Однако хоть и без ошибок выполняется код подгрузки, все равно далее, при использовании, например fs_iclassesrtti и его "подключении" через DLL и последующей попытке создать скажем экземпляр TStringList вылазит Exception с сообщением о том, что тип TStringList не найден !
Написал обертку…
Написал каркас библиотеки
После компиляции библиотеки пытаюсь вызывать
Доктор… где я не прав… как же подгружать компоненты динамически?
В пошаговом режиме видно, что при варианте с dll в процедуре
Не выполняется условие (Item is TfsClassVariable) и найденный Item не TfsClassVariable... пробовал просто убрать условие... падает в экзепшн... как же быть... извелся весь?
For most applications, packages provide greater flexibility and are easier to create than DLLs. However, there are several situations where DLLs would be better suited to your projects than packages:
Your code module will be called from non-Delphi applications.
You are extending the functionality of a Web server.
You are creating a code module to be used by third-party developers.
Your project is an OLE container.
However, if your application includes VisualCLX, you must use packages instead of DLLs. Only packages can manage the startup and shut down of the Qt shared libraries.
You cannot pass Delphi runtime type information (RTTI) across DLLs or from a DLL to an executable. If you pass an object from one DLL to another DLL or an executable, you will not be able to use the is or as operators with the passed object. This is because the is and as operators need to compare RTTI. If you need to pass objects from a library, use packages instead, as these can share RTTI. Similarly, you should use packages instead of DLLs in Web Services because they are rely on Delphi RTTI.
последний абзац? хм... а что такое packages instead?
В fs_doa.pas добавляю две публичные функции
Выдираю имена функций
Переписал вызов
Может где RegisterClass надо вызывать? или что делать? я совершенно запутался... помогите
Но только не этого я хотел добиться… сборка с рантайм пакетами противоречит концепции моей разработки… а объявление пакета расширения еще на этапе сборки… не дает универсальной плагинной архитектуры системы… которой я хотел добиться… много хотел… не подумав но все равно спасибо, что помогли расставить все на свои места