Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  17:57[Войти] | [Зарегистрироваться]
Ответ на вопрос № 83747

24-09-2020 08:03
Есть некая базовая dll, в которой некоторые функции объявлены как EXTERNAL из других dll. Приложение базовую dll загружает в run-time через LoadLibrary.

Потребовалось переместить базовую dll со всеми сопутствующими из каталога с приложением в другое место. Приложение знает путь, по которому расположена базовая dll, однако загрузка не проходит: не находятся сопутствующие dll с реализациями external-функций. Предположительно, они ищутся не в каталоге с базовой dll, а в каталоге с приложением.

Вопрос-максимум: Можно ли как-то указать, чтобы по директиве EXTERNAL dll искались в каталоге с базовой dll, а не в каталоге с приложением? Вариант — указать путь в переменной среды PATH не подходит.

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

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

21-10-2020 07:25 | Сообщение от автора вопроса
Изменять текущий1 каталог стремно: там куча всякого разного, а не одна единственная dll. А вот SetDllDirectory — вариант интересный, при случае буду иметь в виду.

В проекте же заменили статическую загрузку dll на динамическую с конкретизацией пути к файлу. Вроде как, работает.

11-10-2020 14:29
А также, можно воспользоваться функцией SetDllDirectory для изменения стандартного пути поиска файлов DLL.
https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setdlldirectorya

11-10-2020 14:19
По поводу ответа господина Python.

Используя ChDir(), нужно помнить, что текущая директория может быть совсем не та, которую ожидает программист.
Соответственно и результат может быть неожиданным.

Например, в ярлыке программы может быть указана директория запуска, отличная от месте, где лежит исполняемый файл.
Или программу запустили иным способом, например, из командной строки, но не её из текущей директории.
Ещё некоторые стандартные диалоги могут коварным образом менять текущую директорию - например, диалог выбора файла.

Нельзя рассчитывать, что текущая директория будет всегда та, которая была при загрузке, и что она совпадает с директорией exe-шника.

По сути вопроса.
Возможно, размещать DLL в поддиректории поможет этот механизм:
https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-redirection

11-10-2020 04:56 | Комментарий к предыдущим ответам
Большое спасибо Python за то, что он с пониманием отнёсся к моей лени и проверил моё предположение! :)

09-10-2020 12:34
Поигрался с библиотеками. Итак, вот результаты. Вкратце: если дочерняя библиотека и все её подчинённые библиотеки лежат в одной папке, то нужно ПЕРЕД LoadLibrary установить ChDir (или другим способом) эту директорию как текущую, а ПОСЛЕ LoadLibrary - вернуть всё на место. Тогда LoadLibrary подцепит статически слинкованные библиотеки корректно.
Первая библиотека (DLL улетит в папку SubFolder, которая лежит в каталоге исполняемого файла).

library Child1;

Function ChildProc1(Arg1,Arg2:integer):integer;stdcall;
begin
           Result:=Arg1+Arg2;
end;

exports ChildProc1;

begin
end.


Вторая библиотека идентична (просто для примера и также улетает в SubFolder):

library Child2;

function ChildProc2(Arg1,Arg2:integer):integer;stdcall;
begin
           Result:=Arg1*Arg2;
end;

exports ChildProc2;

begin
end.


Мастер-библиотека (тоже в SubFolder, статическая линковка с дочками):

library MainLib;

uses
           Windows, SysUtils;

Function ChildProc1(Arg1,Arg2:integer):integer;stdcall;external 'Child1.dll';
function ChildProc2(Arg1,Arg2:integer):integer;stdcall;external 'Child2.dll';

procedure ShowResults(Arg1,Arg2:integer);stdcall;
var
           S:string;
begin
           S:=Format('Результаты: запрос %d, %d первый %d, второй %d',[Arg1,Arg2,ChildProc1(Arg1,Arg2),ChildProc2(Arg1,Arg2)]);
           MessageBox(0,PChar(S),'Информация',MB_ICONINFORMATION);
end;

exports ShowResults;
begin
end.


Ну и код вызова:

Type
           TShowResult=procedure(Arg1,Arg2:integer);stdcall;

procedure TForm1.Button1Click(Sender: TObject);
var
           HLib:THandle;
           Proc:TShowResult;
begin
           ChDir('SubFolder');
           HLib:=LoadLibrary('MainLib.dll');
           if HLib=0 then
                     RaiseLastOSError;
           try
                     Proc:=GetProcAddress(HLib,'ShowResults');
                     if @Proc=nil then
                               RaiseLastOSError;
                     Proc(1,32);
           finally
                     FreeLibrary(HLib);
                     ChDir('..');
           end;
end;


30-09-2020 12:41 | Сообщение от автора вопроса
Если положить в System32 (или любой другой каталог из PATH), то, скорее всего, загрузится. Но меня не устраивает, так как заказчик сам выбирает каталог, куда положить библиотеки.

Текущий каталог в случае с DLL, как я понимаю, это каталог вызывающего приложения, а не каталог с базовой DLL. Опытным путем вычилено.

28-09-2020 11:07 | Комментарий к предыдущим ответам
А допустимо ли положить базовую и сопутствующие dll в какую-нибудь System32?
Размышления вслух: вроде как после каталога приложения проверяется текущий каталог. Может в приложении изменить его?

24-09-2020 12:56 | Сообщение от автора вопроса
На вопрос-минимум, кажется, сам нашел ответ:

  StrLen:=GetModuleFileName(hInstance,Buf,BufSize);



А вот от статической загрузки, похоже, придется отказываться :(

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Раз дощечка, два дощечка будет лесенка. Раз словечко, два словечко, будет ЧТО?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования