Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как динамически создать и выполнить код в Delphi? 
:(
    Опции темы
Andrey_P
Дата 27.8.2005, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 22.12.2003
Где: Томск

Репутация: нет
Всего: нет



Суть в следующем... есть у меня компонент, имеет он 2 события - OnEnter и OnExit.
Пользователю я даю возможность в специально предоставленном Memo ввести некоторое количество строк кода на Delphi.
При этом значения переменных известны, код (к примеру, OnEnter) должен отработать и вернуть те же переменные, но уже измененные, с другими значениями. При следующем наступлении события берутся уже новые значения переменных и код работает еще раз...

Я динамически создал dpr-файл на Delphi, скомпилировал его программно с помощью dcc32,
но вот беда - готовый exe-шник мне надо запускать 1000 и более раз в рамках однократного выполнения моей большой программы. 1000-кратный запуск занимает 100 секунд, даже если в этом exe-шнике записан лишь один оператор (a:= 1). Это очень много, надо быстрее.

Какие еще есть варианты того, что пользователь ввел код, какой хочет на Delphi, а моя программа бы его выполнила? Есть подозрение, что можно с помощью dll, как думаете - даст это результат или нет. Как программно создать dll и вызывать ее функции?
Писать собственный компилятор или интерпретатор уже нет сил и времени... (может у кого-то есть готовый? - грамматика: Delphi).



PM MAIL   Вверх
p0s0l
Дата 27.8.2005, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Цитата(Andrey_P @ 27.8.2005, 14:22)
Есть подозрение, что можно с помощью dll, как думаете - даст это результат или нет. Как программно создать dll и вызывать ее функции?
Результат конечно же даст, и очень неплохой. Делается точно так же, как ты создавал exe, только вместо program - library и код заключи в экспортируемую функцию. А как вызывать функцию из DLL - это тыщу раз задавалось на форуме, поищи...

Цитата(Andrey_P @ 27.8.2005, 14:22)
Писать собственный компилятор или интерпретатор уже нет сил и времени... (может у кого-то есть готовый? - грамматика: Delphi).
Я немного использовал только Innerfuse Pascal Script... Но имхо, лучше через DLL делать...


--------------------
С уважением, г-н Посол.
PM   Вверх
Andrey_P
Дата 27.8.2005, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 22.12.2003
Где: Томск

Репутация: нет
Всего: нет



Работало долго почему? 100% из-за ShellExecute. Через dll заметно быстрее будет или нет?

PM MAIL   Вверх
p0s0l
Дата 27.8.2005, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Цитата(Andrey_P @ 27.8.2005, 14:33)
Работало долго почему? 100% из-за ShellExecute. Через dll заметно быстрее будет или нет?
Конечно из-за создания нового процесса.
Если будешь1 раз компилить DLL и 1000 раз вызывать функцию из неё, то никаких лишних телодвижений не надо будет делать. Быстрее этого сделать будет уже нельзя... Если будет тормозить - то только из-за тормозного кода, который выполняется (то что вводится в Memo)...
Как вариант - модернизировать exe (в смысле компилируемый код) так, чтобы он сам выполнял 1000 раз функцию, а не 1000 раз запускать exe smile


--------------------
С уважением, г-н Посол.
PM   Вверх
Andrey_P
Дата 27.8.2005, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 22.12.2003
Где: Томск

Репутация: нет
Всего: нет



Огромное человеческое спасибо за помощь.
PM MAIL   Вверх
Alex
Дата 27.8.2005, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 6
Всего: 162



Andrey_P, обратите внимание на http://www.fastreport.ru/ru/products/products.php?BID=5 может это то, что вы ищите.


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
Andrey_P
Дата 27.8.2005, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 22.12.2003
Где: Томск

Репутация: нет
Всего: нет



Alex не скачиваются у меня файлы оттуда почему-то.. smile
Добавлено @ 15:06
p0s0l, а как быть, если компонентов этих с событиями OnEnter и OnExit (см. 1-й пост) в модели несколько, соответственно нужно несколько dll с разными именами
(например, MyComponent1OnEnter.dll, MyComponent1OnExit.dll, MyComponent124OnEnter.dll, MyComponent124OnExit.dll и т.д.). Нужно же их прописывать в uses секции или необязательно?
Когда я вызывал exe-шник, я не задумывался, а просто писал в качестве параметра ShellExecute имя файла. С dll-кой я могу сделать что-то подобное?
PM MAIL   Вверх
Alex
Дата 27.8.2005, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 6
Всего: 162



Цитата(Andrey_P @ 27.8.2005, 16:02)
Alex не скачиваются у меня файлы оттуда почему-то..

Все нормально там скачивается http://www.fastreport.ru/pbc_download/fsd7.exe


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
Andrey_P
Дата 27.8.2005, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 22.12.2003
Где: Томск

Репутация: нет
Всего: нет



Точно, скачалось. У меня просто FlashGet глючил что-то. Спасибо за ссылки, ща посмотрю
PM MAIL   Вверх
Andrey_P
Дата 27.8.2005, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 22.12.2003
Где: Томск

Репутация: нет
Всего: нет



Alex, ты его случайно не покупал? Как он, нормально работает? Похоже, это действительно то, что мне нужно!
PM MAIL   Вверх
Alex
Дата 27.8.2005, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 6
Всего: 162



Отдельно его не покупал, но уже два года пользуюсь построителем отчетов FastReport, в который входит FS притензий к FS у меня небыло хотя иногда довольно сложные выражения расчетов на нем писались


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
Andrey_P
Дата 27.8.2005, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 22.12.2003
Где: Томск

Репутация: нет
Всего: нет



Сделал я по 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 я не получил. Что делать?
Уже руки опускаются smile
PM MAIL   Вверх
Alex
Дата 27.8.2005, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 6
Всего: 162



Я конечно не спец в этом вопросе, но я бы начал копать все же в сторону FS. Так как он встроен и очень активно используется в FastReport и тормозов я там не замечал


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
Andrey_P
Дата 27.8.2005, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 22.12.2003
Где: Томск

Репутация: нет
Всего: нет



Его еще купить надо smile. Да и вообще, разобраться хочу с этим. Но FS все равно, скорее всего, впоследствии приобрету.
PM MAIL   Вверх
p0s0l
Дата 28.8.2005, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Цитата(Andrey_P @ 27.8.2005, 17:34)
Для 200 событий программа работает секунд 10 примерно, даже если в коде процедуры (в dll-ке) всего один оператор.
Этого быть не может.
100% ты что-то неправильно сделал.
Покажи текст dpr (длл-ки), который ты компилишь с помощью dcc32, и код загрузки DLL и вызова процедур из DLL...

Цитата(Andrey_P @ 27.8.2005, 15:02)
Нужно же их прописывать в uses секции или необязательно?
Кого прописывать в uses, не понял ?
Если у тебя 100 событий, значит, либо нужно сделать 100 экспортируемых процедур в 1 DLL, либо сделать 100 DLL (первый вариант определенно лучше). Загружаешь библиотеку с помощью LoadLibrary, получаешь адрес функций (GetProcAddress), потом когда надо их вызываешь. Тормозов при вызове не будет.


--------------------
С уважением, г-н Посол.
PM   Вверх
Andrey_P
Дата 1.9.2005, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 22.12.2003
Где: Томск

Репутация: нет
Всего: нет



pOsOl,


Вот текст dpr-ки, которая компилируется в dll.



Код

library OnExit1;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes, IniFiles;

var
  Ini: TIniFile;

  MasI: Array [0..99] of Integer;
  MasS: Array [0..99] of String;

procedure CodeExecute;
begin
  Ini:= TIniFile.Create ('C:\Program Files\Borland\Delphi7\Projects\Simulation\params.ini');

  MasI[0]:= Ini.ReadInteger ('Integer', 'Var1', 0);
  MasI[1]:= Ini.ReadInteger ('Integer', 'Var2', 0);
  MasI[2]:= Ini.ReadInteger ('Integer', 'Var3', 0);
  MasI[3]:= Ini.ReadInteger ('Integer', 'Const1', 0);


  MasS[0]:= Ini.ReadString('String', 'In1.DestPort', '');


  MasI[1]:= 34;
  MasI[0]:= MasI[1] div 2;
  MasI[2]:= 1;
  

  Ini.WriteInteger ('Integer', 'Var1', MasI[0]);
  Ini.WriteInteger ('Integer', 'Var2', MasI[1]);
  Ini.WriteInteger ('Integer', 'Var3', MasI[2]);
  Ini.WriteInteger ('Integer', 'Const1', MasI[3]);

  Ini.WriteString ('String', 'In1.DestPort', MasS[0]);


  Ini.Free;
end;

exports
  CodeExecute index 1;

begin
end.





[b]
Вот загрузка
[/b]


  FExitHandle:= LoadLibrary (PChar (Dir + 'OnExit' + IntToStr (FID) + '.dll'));
  if (FExitHandle >= 32)
  then begin
    FLoadedExit:= True;
    FExitProc:= GetProcAddress (FExitHandle, 'CodeExecute');
  end
  else begin
    if (MessageDlg ('Error', mtError, [mbOk], 0) = mrOK)
    then FLoadedExit:= False;
  end;


вызов такой:

if FLoadedExit
then FExitProc;

Я заказал fastScript кстати, так и не разобравшись с dll-ками smile. Если увидишь, где косяки, пиши, буду очень рад.
p0s0l

Это сообщение отредактировал(а) Girder - 1.9.2005, 21:15
PM MAIL   Вверх
p0s0l
Дата 1.9.2005, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



То что написано - то всё верно. Ошибка у тебя где-то зарыта не тут, где-то вкралась не заметно... Тебе её всё равно придётся найти, т.к. если ты просто заменишь вызов функции из DLL на выполнение скрипта, тормоза будут эти же самые, даже больше.

Для убедительности прикрепляю файлик, открывай Project1.dpr и запускай его. Там ты увидишь, что вызов приведенной тобой функции из DLL нисколько не тормозит (200 вызовов за 170 мс), в то время как запуск .exe 200 раз выполняется за 4-5 сек... Как у тебя 10 секунд получается - не знаю даже...

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  DLL.ZIP 7,90 Kb


--------------------
С уважением, г-н Посол.
PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0720 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.