![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
![]() Всем привет!
Ситуация такая. Объявил я процедуры таким образом: Код:
procedure LoadSkin(lpszPath: String; lpszIniFileName: String); stdcall; external 'isskin.dll'; // Importing UnloadSkin API from ISSkin.DLL procedure UnloadSkin(); stdcall; external 'isskin.dll'; В ресурсах программы прячу dll - библиотеку. При создании формы она должна распаковываться в ТЕМП, ну а потом начинаю работать с библиотекой.. Вообщем проблема в том, что при запуски программы я получаю ошибку, что библиотека не найдена... если ее положить конечно в папку с программой тогда работает... что можно сделать? |
#2
|
|||
|
|||
![]() Загружать ее динамически через LoadLibrary. Статическая линковка так работать не будет - библиотека в таком случае должна быть доступна на момент загрузки приложения, т.к. при статической линковке за загрузку всех требуемых библиотек отвечает операционная система.
|
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
Alloc (02.06.2015)
|
#3
|
||||
|
||||
![]() Да, только LoadLibrary, GetProcAddress и прочие танцы с бубном. Для особо упоротых существует код для ручной загрузки библиотеки прямо из оперативки, без сохранения на диск. Но лучше подобной фигнёй не заниматься - это плохая практика: во-первых, это неудобно, а во-вторых, передать программу в виде установщика/архива ничуть не сложнее, и при этом по системе не будут разбрасываться всякие сомнительные исполняемые файлы и загаживать место.
jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 02.06.2015 в 12:45. |
Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
Alloc (02.06.2015)
|
#4
|
||||
|
||||
![]() Спасибо за ответы. Если не сложно, не могли бы вы предоставить небольшой пример как это происходит, для реализации поставленной задачи?
Т.е. библиотеку все равно придется распаковать и загрузить в память при помощи LoadLibrary(LibFileName: PChar)... может можно как то напрямую из ресурсов ее загрузить...? я немного не понимаю, объясните пожалуйста |
#5
|
||||
|
||||
![]() В LoadLibrary передается путь к библиотеке. Она возвращает описатель загруженной библиотеки (насколько я помню, это обычный указатель на ее начало в памяти). Потом через GetProcAddress с использованием этого указателя нужно найти все требуемые функции из DLL и сохранить в переменных типа "функция". Затем вызывать. Это неудобно, но работает.
Грузить прямо из памяти - это извращение, потому что это делается вручную. Код, который я видел - это фактически люди сами писали свой LoadLibrary и GetProcAddress. Сами анализируют таблицы импорта и экспорта библиотеки, применяют релокации и т.д. Самый лучший выход - не заниматься всей этой фигнёй. Просто положить библиотеку рядом и всё. Если передаешь программу кому-то - собери в ZIP или в установщик и передавай его. jmp $ ; Happy End! The Cake Is A Lie. |
Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
Alloc (02.06.2015)
|
#6
|
||||
|
||||
![]() Скажите, вот допустим есть код:
Код:
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; выходит сообщение "Не найдена искомая процедура." пожалуйста подскажите, что не так в коде? Заранее спасибо. |