| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: WinAPI и системное программирование > Как динамически создать и выполнить код в Delphi? |
| Автор: Andrey_P 27.8.2005, 14:22 |
| Суть в следующем... есть у меня компонент, имеет он 2 события - OnEnter и OnExit. Пользователю я даю возможность в специально предоставленном Memo ввести некоторое количество строк кода на Delphi. При этом значения переменных известны, код (к примеру, OnEnter) должен отработать и вернуть те же переменные, но уже измененные, с другими значениями. При следующем наступлении события берутся уже новые значения переменных и код работает еще раз... Я динамически создал dpr-файл на Delphi, скомпилировал его программно с помощью dcc32, но вот беда - готовый exe-шник мне надо запускать 1000 и более раз в рамках однократного выполнения моей большой программы. 1000-кратный запуск занимает 100 секунд, даже если в этом exe-шнике записан лишь один оператор (a:= 1). Это очень много, надо быстрее. Какие еще есть варианты того, что пользователь ввел код, какой хочет на Delphi, а моя программа бы его выполнила? Есть подозрение, что можно с помощью dll, как думаете - даст это результат или нет. Как программно создать dll и вызывать ее функции? Писать собственный компилятор или интерпретатор уже нет сил и времени... (может у кого-то есть готовый? - грамматика: Delphi). |
| Автор: p0s0l 27.8.2005, 14:32 | ||||
|
| Автор: Andrey_P 27.8.2005, 14:33 |
| Работало долго почему? 100% из-за ShellExecute. Через dll заметно быстрее будет или нет? |
| Автор: p0s0l 27.8.2005, 14:39 | ||
Если будешь1 раз компилить DLL и 1000 раз вызывать функцию из неё, то никаких лишних телодвижений не надо будет делать. Быстрее этого сделать будет уже нельзя... Если будет тормозить - то только из-за тормозного кода, который выполняется (то что вводится в Memo)... Как вариант - модернизировать exe (в смысле компилируемый код) так, чтобы он сам выполнял 1000 раз функцию, а не 1000 раз запускать exe |
| Автор: Andrey_P 27.8.2005, 14:43 |
| Огромное человеческое спасибо за помощь. |
| Автор: Alex 27.8.2005, 14:54 |
| Andrey_P, обратите внимание на http://www.fastreport.ru/ru/products/products.php?BID=5 может это то, что вы ищите. |
| Автор: Andrey_P 27.8.2005, 15:02 |
| Alex не скачиваются у меня файлы оттуда почему-то.. Добавлено @ 15:06 p0s0l, а как быть, если компонентов этих с событиями OnEnter и OnExit (см. 1-й пост) в модели несколько, соответственно нужно несколько dll с разными именами (например, MyComponent1OnEnter.dll, MyComponent1OnExit.dll, MyComponent124OnEnter.dll, MyComponent124OnExit.dll и т.д.). Нужно же их прописывать в uses секции или необязательно? Когда я вызывал exe-шник, я не задумывался, а просто писал в качестве параметра ShellExecute имя файла. С dll-кой я могу сделать что-то подобное? |
| Автор: Alex 27.8.2005, 15:23 | ||
Все нормально там скачивается http://www.fastreport.ru/pbc_download/fsd7.exe |
| Автор: Andrey_P 27.8.2005, 15:26 |
| Точно, скачалось. У меня просто FlashGet глючил что-то. Спасибо за ссылки, ща посмотрю |
| Автор: Andrey_P 27.8.2005, 15:36 |
| Alex, ты его случайно не покупал? Как он, нормально работает? Похоже, это действительно то, что мне нужно! |
| Автор: Alex 27.8.2005, 15:57 |
| Отдельно его не покупал, но уже два года пользуюсь построителем отчетов FastReport, в который входит FS притензий к FS у меня небыло хотя иногда довольно сложные выражения расчетов на нем писались |
| Автор: Andrey_P 27.8.2005, 17:34 |
| Сделал я по 2 библиотеки для каждого компонента, из своего кода (программно) их компилирую примерно так: CreateProcess (nil, PChar ('dcc32.exe ' + FileName + '.dpr'), nil, nil, False, CREATE_NEW_PROCESS_GROUP, nil, PChar (Directory), Si, P); Компилируется один раз за все время выполнения модели, в самом начале, так что время компиляции для меня некритично. Затем для каждого компонента (после явной загрузки библиотек в память) я нахожу адреса процедур CodeExecute и выполняю эти процедуры каждый раз при наступлении события OnEnter и OnExit. Для 200 событий программа работает секунд 10 примерно, даже если в коде процедуры (в dll-ке) всего один оператор. Так что ощутимого улучшения по сравнению с ShellExecute я не получил. Что делать? Уже руки опускаются |
| Автор: Alex 27.8.2005, 18:40 |
| Я конечно не спец в этом вопросе, но я бы начал копать все же в сторону FS. Так как он встроен и очень активно используется в FastReport и тормозов я там не замечал |
| Автор: Andrey_P 27.8.2005, 19:01 |
| Его еще купить надо |
| Автор: p0s0l 28.8.2005, 19:49 | ||||
100% ты что-то неправильно сделал. Покажи текст dpr (длл-ки), который ты компилишь с помощью dcc32, и код загрузки DLL и вызова процедур из DLL...
Если у тебя 100 событий, значит, либо нужно сделать 100 экспортируемых процедур в 1 DLL, либо сделать 100 DLL (первый вариант определенно лучше). Загружаешь библиотеку с помощью LoadLibrary, получаешь адрес функций (GetProcAddress), потом когда надо их вызываешь. Тормозов при вызове не будет. |
| Автор: Andrey_P 1.9.2005, 14:44 | ||
| pOsOl, Вот текст dpr-ки, которая компилируется в dll.
вызов такой: if FLoadedExit then FExitProc; Я заказал fastScript кстати, так и не разобравшись с dll-ками p0s0l |
| Автор: p0s0l 1.9.2005, 15:47 |
| То что написано - то всё верно. Ошибка у тебя где-то зарыта не тут, где-то вкралась не заметно... Тебе её всё равно придётся найти, т.к. если ты просто заменишь вызов функции из DLL на выполнение скрипта, тормоза будут эти же самые, даже больше. Для убедительности прикрепляю файлик, открывай Project1.dpr и запускай его. Там ты увидишь, что вызов приведенной тобой функции из DLL нисколько не тормозит (200 вызовов за 170 мс), в то время как запуск .exe 200 раз выполняется за 4-5 сек... Как у тебя 10 секунд получается - не знаю даже... |