![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
![]() Всем привет!
Первый опыт работы с dll, нашёл подробный пример создания, подключения и работы с dll на сайте pro.dtn.ru. Сделал всё как в примере: 1)Объявил процедурную переменную или процедурный тип, описывающий подпрограмму, которую нужно вызвать. 2)Вызвал функцию LoadLibrary для загрузки библиотеки DLL. 3)Вызвал функцию GetProcAddress для получения указателя на подпрограмму в библиотеке DLL. 4)Вызвал подпрограмму. 5)Вызвал функцию FreeLibrary для выгрузки библиотеки DLL. Выскакивает ошибка, не могу понять где накосячил или глаз уже замылился - не вижу. Короче, по порядку: Есть форма с большим количеством текстовых полей, и есть кусок кода который не даёт вводить в Edit что-либо кроме чисел действительных или целых. Реализовано это так: Код:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); var rez:string; znak,key: char; begin rez:= FloatToStr(1/2); rez:= copy(rez,2,1); znak:= rez[1]; if (key = '.') and (key <> znak) then key:=znak; if (key = ',') and (key <> znak) then key:=znak; if key in ['a'..'z'] then key := #0; //Не даёт вводить буквы из множества a-z if (key = 'й')or(key = 'ц') or(key = 'у') or(key = 'к')or(key = 'е')or(key = 'н') or(key = 'г')or(key = 'ш')or(key = 'щ')or(key = 'з')or(key = 'х')or(key = 'ъ') or(key = 'ф')or(key = 'ы')or(key = 'в')or(key = 'а')or(key = 'п')or(key = 'р') or(key = 'о')or(key = 'л')or(key = 'д')or(key = 'ж')or(key = 'э')or(key = 'я') or(key = 'ч')or(key = 'с')or(key = 'м')or(key = 'и')or(key = 'т')or(key = 'ь') or(key = 'б')or(key = 'ю')then key := #0; if (key = '\')or (key = '/') or (key = '*')or (key = '+') or (key = '-')or (key = '`')or (key = '=')or (key = '[')or (key = ']')or (key = ';')or (key = '!')or (key = '@')or (key = '#') or (key = '$')or (key = '%')or (key = '^')or (key = '&')or (key = '(') or (key = ')')or (key = '_')or (key = '`')then key := #0; //Не даёт вводить арифмет. символы } end; Этот фрагмент в коде программы повторяется очень часто, что делает код громоздким и трудночитаемым. Поэтому я решил засунуть этот фрагмент в dll в виде процедуры и вызывать её когда мне нужно. реализовано это так: Код:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); var DLLRoutine: procedure; //объявление процедурной переменной DllHandle: THandle; begin try //Загружаем 'Tube_Smoke.dll' DLLHandle := LoadLibrary('Tube_Smoke.dll'); finally FreeLibrary(DLLHandle); ShowMessage('Не удалось загрузить DLL ...'); end; try { DLLRoutine указывает на процедуру 'Check_Edit' в файле 'Tube_Smoke.dll' } DLLRoutine := GetProcAddress(DLLHandle,'Check_Edit'); { Вызываем процедуру 'Check_Edit' } if Assigned(DLLRoutine) then DLLRoutine; if GetProcAddress(DLLHandle,'Check_Edit') = nil then ShowMessage('Не удалось получить доступ к процедуре...'); finally FreeLibrary(DLLHandle); end; // Конец блока try..finally end; Файл dll кинул в папку проекта и в папку debug где эгзешник. Сама dll: Код:
library Tube_Smoke; { Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses System.SysUtils,System.Classes; {$R *.res} procedure Check_Edit; var rez:string; znak,key: char; begin rez:= FloatToStr(1/2); rez:= copy(rez,2,1); znak:= rez[1]; if (key = '.') and (key <> znak) then key:=znak; if (key = ',') and (key <> znak) then key:=znak; if key in ['a'..'z'] then key := #0; //Не даёт вводить буквы из множества a-z if (key = 'й')or(key = 'ц') or(key = 'у') or(key = 'к')or(key = 'е')or(key = 'н') or(key = 'г')or(key = 'ш')or(key = 'щ')or(key = 'з')or(key = 'х')or(key = 'ъ') or(key = 'ф')or(key = 'ы')or(key = 'в')or(key = 'а')or(key = 'п')or(key = 'р') or(key = 'о')or(key = 'л')or(key = 'д')or(key = 'ж')or(key = 'э')or(key = 'я') or(key = 'ч')or(key = 'с')or(key = 'м')or(key = 'и')or(key = 'т')or(key = 'ь') or(key = 'б')or(key = 'ю')then key := #0; if (key = '\')or (key = '/') or (key = '*')or (key = '+') or (key = '-')or (key = '`')or (key = '=')or (key = '[')or (key = ']')or (key = ';')or (key = '!')or (key = '@')or (key = '#') or (key = '$')or (key = '%')or (key = '^')or (key = '&')or (key = '(') or (key = ')')or (key = '_')or (key = '`')then key := #0; //Не даёт вводить арифмет. символы end; exports Check_Edit; begin end. Срабатывает обработчик исключений. Не пойму почему... И так и сяк вертел.... И через функцию пробовал... Может кто ни будь, кинет на форму один Edit и попробует "исполнить" так сказать на бис ? Как завещал товарищ Ленин: УЧИТЬСЯ! УЧИТСЯ! И ЕЩЁ РАЗ УЧИЦЦА! |
#2
|
||||
|
||||
![]() Посмотрел твой исходник.
Это шутка, да? До 1 апреля, вроде, далековато. Хей-хей-хей! Только не ходите в мой сарай, лады?.. |
#3
|
||||
|
||||
![]() Код:
try //Загружаем 'Tube_Smoke.dll' DLLHandle := LoadLibrary('Tube_Smoke.dll'); finally FreeLibrary(DLLHandle); ShowMessage('Не удалось загрузить DLL ...'); end; try { DLLRoutine указывает на процедуру 'Check_Edit' в файле 'Tube_Smoke.dll' } DLLRoutine := GetProcAddress(DLLHandle,'Check_Edit'); { Вызываем процедуру 'Check_Edit' } if Assigned(DLLRoutine) then DLLRoutine; Пишу программы за еду. __________________ |
#4
|
|||
|
|||
![]() В первом примере- что делает в процедуре локальная переменная key, которая имеет то же имя, что и формальный параметр?
во втором примере, а где параметры процедуры? |
#5
|
|||
|
|||
![]() Извращенцы. Микроскопом гвозди забивать не пробовали? Говорят, тоже хорошо вставляет, особенно когда осколки линз во все стороны летят...
Для данной задачи не нужно ничего, кроме ОДНОГО простого обработчика, присвоенного ВСЕМ едитам. Код:
procedure TForm1.EditKeyPress(Sender : TObject; var Key : Char); begin if Not (Key In ['0'..'9','.',#8]) Then Key := #0 Else If Key = '.' Then If Pos('.',(Sender As TEdit).Text) > 0 Then Key := #0; end; |
#6
|
||||
|
||||
![]() Цитата:
От тиражирования одного и того-же фрагмента кода я как раз и пытаюсь уйти , а ты мне предлагаешь те-же яйца только в профиль - "присвой этот обработчик всем едитам" Твой код на первый взгляд оптимизирован лучше... но во первых знак разделения дробных чисел может быть не "." а "," - это зависит от настроек конкретной ОС, а для меня важно что-бы они совпадали; во вторых защита от ввода не нужных символов в данном случае не самоцель. Главное хотелось бы освоить работу с DLL... С чего-то начинать нужно.. |
#7
|
||||
|
||||
![]() to NumLock
Не понял, почему я её сразу же освобождаю ?!? Я её освобождаю только если не удалось выполнить Код:
DLLHandle := LoadLibrary('Tube_Smoke.dll'); Как завещал товарищ Ленин: УЧИТЬСЯ! УЧИТСЯ! И ЕЩЁ РАЗ УЧИЦЦА! Последний раз редактировалось Homo-Fantasmus, 30.10.2015 в 22:54. |
#8
|
||||
|
||||
![]() Цитата:
В исходнике только проект библиотеки ... Сарказм по поводу отсутствия основного проекта или c dll всё так плохо? Основной проект много весит. Кинь на форму один Edit и попробую по событию OnKeyPress выполнить процедуру из dll. Как завещал товарищ Ленин: УЧИТЬСЯ! УЧИТСЯ! И ЕЩЁ РАЗ УЧИЦЦА! |
#9
|
||||
|
||||
![]() Цитата:
А вообще-то lmikle совершенно прав. jmp $ ; Happy End! The Cake Is A Lie. |
#10
|
||||
|
||||
![]() Цитата:
Да, косяк. Вот к чему приводит бездумное копирование чужого кода. Досадно когда тратишь кучу времени на поиск подходящего материала, а тебе подсовывают заведомо не рабочий код. Заменил на except. Код:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); var DLLRoutine: procedure; //объявление процедурной переменной DllHandle: THandle; begin try //Загружаем 'Tube_Smoke.dll' DLLHandle := LoadLibrary('Tube_Smoke.dll'); except FreeLibrary(DLLHandle); ShowMessage('Не удалось загрузить DLL ...'); end; try { DLLRoutine указывает на процедуру 'Check_Edit' в файле 'Tube_Smoke.dll' } DLLRoutine := GetProcAddress(DLLHandle,'Check_Edit'); { Вызываем процедуру 'Check_Edit' } if Assigned(DLLRoutine) then DLLRoutine; if GetProcAddress(DLLHandle,'Check_Edit') = nil then ShowMessage('Не удалось получить доступ к процедуре...'); except FreeLibrary(DLLHandle); end; end; Компилирует без ошибок, но и процедура не работает - в Edit удаётся забить буквы и арифметические символы. |
#11
|
||||
|
||||
![]() Ну еще бы она работала. Вызывается процедура, в какую-то свою локальную переменную что-то зачем-то пишет. И? Она даже не принимает на вход нажатую клавишу, не говоря уже о каких-то выходных результатах.
jmp $ ; Happy End! The Cake Is A Lie. |