Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 02.06.2015, 03:27
Аватар для Alloc
Alloc Alloc вне форума
Начинающий
 
Регистрация: 17.09.2014
Сообщения: 104
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Как объявить процедуру из dll библиотеки?

Всем привет!

Ситуация такая. Объявил я процедуры таким образом:
Код:
procedure LoadSkin(lpszPath: String; lpszIniFileName: String);
stdcall; external 'isskin.dll';

// Importing UnloadSkin API from ISSkin.DLL
procedure UnloadSkin();
stdcall; external 'isskin.dll';

В ресурсах программы прячу dll - библиотеку. При создании формы она должна распаковываться в ТЕМП, ну а потом начинаю работать с библиотекой..

Вообщем проблема в том, что при запуски программы я получаю ошибку, что библиотека не найдена... если ее положить конечно в папку с программой тогда работает...

что можно сделать?
Ответить с цитированием
  #2  
Старый 02.06.2015, 04:55
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,087
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Загружать ее динамически через LoadLibrary. Статическая линковка так работать не будет - библиотека в таком случае должна быть доступна на момент загрузки приложения, т.к. при статической линковке за загрузку всех требуемых библиотек отвечает операционная система.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Alloc (02.06.2015)
  #3  
Старый 02.06.2015, 12:29
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Да, только LoadLibrary, GetProcAddress и прочие танцы с бубном. Для особо упоротых существует код для ручной загрузки библиотеки прямо из оперативки, без сохранения на диск. Но лучше подобной фигнёй не заниматься - это плохая практика: во-первых, это неудобно, а во-вторых, передать программу в виде установщика/архива ничуть не сложнее, и при этом по системе не будут разбрасываться всякие сомнительные исполняемые файлы и загаживать место.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 02.06.2015 в 12:45.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
Alloc (02.06.2015)
  #4  
Старый 02.06.2015, 13:20
Аватар для Alloc
Alloc Alloc вне форума
Начинающий
 
Регистрация: 17.09.2014
Сообщения: 104
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Спасибо за ответы. Если не сложно, не могли бы вы предоставить небольшой пример как это происходит, для реализации поставленной задачи?

Т.е. библиотеку все равно придется распаковать и загрузить в память при помощи LoadLibrary(LibFileName: PChar)... может можно как то напрямую из ресурсов ее загрузить...? я немного не понимаю, объясните пожалуйста
Ответить с цитированием
  #5  
Старый 02.06.2015, 13:31
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

В LoadLibrary передается путь к библиотеке. Она возвращает описатель загруженной библиотеки (насколько я помню, это обычный указатель на ее начало в памяти). Потом через GetProcAddress с использованием этого указателя нужно найти все требуемые функции из DLL и сохранить в переменных типа "функция". Затем вызывать. Это неудобно, но работает.
Грузить прямо из памяти - это извращение, потому что это делается вручную. Код, который я видел - это фактически люди сами писали свой LoadLibrary и GetProcAddress. Сами анализируют таблицы импорта и экспорта библиотеки, применяют релокации и т.д.
Самый лучший выход - не заниматься всей этой фигнёй. Просто положить библиотеку рядом и всё. Если передаешь программу кому-то - собери в ZIP или в установщик и передавай его.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
Alloc (02.06.2015)
  #6  
Старый 02.06.2015, 13:58
Аватар для Alloc
Alloc Alloc вне форума
Начинающий
 
Регистрация: 17.09.2014
Сообщения: 104
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Скажите, вот допустим есть код:

Код:
procedure TForm1.btn1Click(Sender: TObject);
type
  TLoadSkin = procedure(lpszPath: String; lpszIniFileName: String);
  var
    DLLInstance : THandle;
    LoadSkin : TLoadSkin;
begin
  DLLInstance := LoadLibrary('ISSkin.dll');
  if DLLInstance = 0 then
  begin
     MessageDlg('Невозможно загрузить DLL', mtError, [mbOK], 0);
     Exit;
  end;
  @LoadSkin := GetProcAddress(DLLInstance, 'LoadSkin');
  if @LoadSkin = nil then
     LoadSkin('Skin.cjstyles','')
  else
     MessageDlg('Не найдена искомая процедура.', mtError, [mbOK], 0);
  FreeLibrary(DLLInstance);
end;

выходит сообщение "Не найдена искомая процедура."

пожалуйста подскажите, что не так в коде? Заранее спасибо.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 20:15.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025