Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Динамическая загрузка DLL

Delphi , Файловая система , DLL и PlugIns

Динамическая загрузка DLL

Оформил: DeeCo
Автор: http://www.swissdelphicenter.ch

{ 
  There are two possibilities to load a dll: 

  1. Static loading of a DLL means that the DLL is loaded when the application is executed. 
     This is the easier option to dynamic loading, as you'll see, however it means that if the DLL 
     is missing, your program will not run. 
}
   {Examples:}

   {a. Import a function called MYImportFunction from MYLIBRARY.dll}

   procedure MYImportFunction; external 'MYLIBRARY.dll';

   {b. Import a routine under a different name from the one it has in the library. }
   procedure MYImportFunction; external 'MYLIBRARY.dll' name 'MyNewImportFunctionName';

   {c. By ordinal value: Has to be the same value as when using the exports 
      keyword when making the DLL}
   procedure MYImportFunction; external 'MYLIBRARY.dll' index 10;


 { 
  2. Dynamic loading 

  By dynamically loading a DLL you decide at runtime which DLL to use. 
  This means you can give your program different functionality depending on which 
  DLL's are present (freeware or shareware versions of a program). 
  Or also if you want to load a library whose name or path must be computed at 
  run time or generated from user input. 

  Dynamic loading of a DLL loads the DLL in your application when 
  it is needed and unload it once you its work is done. 
  It requires more code to use, 
  however it more resource friendly than static loading. 
}

 {**********************************************************}

 { 
  Es gibt zwei Mцglichkeiten, eine DLL zu laden. 

  1. Statisches Laden 

  Beim statischen Laden wird die zu importierende Prozedur/Funktion mit "external" deklariert. 
  Die Datei 'MYLIBRARY.DLL' wird dann beim Programmstart geladen. 
}

   {Beispiele:}

   {a. Importiert eine Funktion MYImportFunction aus der Dll MYLIBRARY.dll }
   procedure MYImportFunction; external 'MYLIBRARY.dll';

   {b. Man kann auch eine Routine unter einem anderen Namen importieren als der in der dll. }
   procedure MYImportFunction; external 'MYLIBRARY.dll' name 'MyNewImportFunctionName';

   {c. Einen Index angeben: }
   procedure MYImportFunction; external 'MYLIBRARY.dll' index 10;


   // 2. Dynamisches Laden 

{ 
  Beim Dynamischen Laden erfolgt der Zugriff auf die Routinen mit 
  direkten Windows-API-Aufrufen (LoadLibrary, FreeLibrary, GetProcAddress). 
  Die importierten Routinen werden ьber prozedurale Variablen referenziert. 

  Die importierten DLLs werden erst bei der Ausfьhrung des Quelltextes geladen. 
  Somit wird Speicherplatz eingespart und das Programm wird auch ausgefьhrt, 
  wenn einige DLLs fehlen. 
}

 {**********************************************************}

 // Example for dynamically loading a DLL 
// Beispiel um eine Dll dynamisch zu laden: 


type
   TDLLFunction = function(someParam: TSomeType): TSomeOtherType;

 { 
  To execute such a function by name from a named DLL one could use a 
  "caller" function like 
}

 function CallDLLFunction(const dllname, functionname: string;
   theParameter: TSomeType): TSomeOtherType;
 var
   hDLL: THandle;
   theFunction: TDLLFunction;
   buf: array [0..144] of Char;
 begin
   // Get a handle to the DLL module. 
  // das Handle zum DLL Modul ermitteln. 
  hDLL := LoadLibrary(StrPCopy(buf, dllname));
   // If the handle is valid, try to get the function address. 
  // Wenn das Handle gьltig ist, versuche die Adresse der Funktion zu ermitteln 
  if hDLL <> 0 then
   begin
     // Return the address of the specified exported (DLL) function. 
    // Adresse der Dll-Funktion ermitteln 
    try
       @theFunction := GetProcAddress(hDll, StrPCopy(buf, functionname));
       // If the function address is valid, call the function. 
      // Wenn die Funktion gefunden wurde... 
      if @theFunction <> nil then
         Result := theFunction(theParameter)
       else
         raise EDLLException.CreateFmt('Unable to link to function %s in DLL %s!',
           [functionname, dllname]);
     finally
       // Free the DLL module. 
      // Dll wieder freigeben. 
      FreeLibrary(hDLL);
     end;
   end
   else
     raise EDLLException.CreateFmt('Unable to load DLL %s!'#13#10 +
       'Reason: %s.', [dllname, DLLErrors[hDLL]]);
 end;

Это код-набор на языке Delphi, демонстрирующий динамическое загрузку и использование динамической библиотеки (DLL) в приложении Delphi. Код предлагает два способа загрузки DLL: статический и динамический.

Статическая загрузка В статической загрузке DLL загружается, когда приложение запускается. Это означает, что если DLL отсутствует, программа не будет работать. Код использует ключевое слово external для объявления процедуры из DLL, как это:

procedure MYImportFunction; external 'MYLIBRARY.dll';

Ключевое слово external informs Delphi that the procedure is defined in an external library (the DLL). The 'MYLIBRARY.dll' parameter specifies the name of the DLL file.

Динамическая загрузка В динамической загрузке DLL загружается только когда она нужна. Это означает, что если DLL отсутствует, программа будет работать, но без функциональности, предоставляемой DLL. Код использует прямые вызовы Windows API (LoadLibrary, FreeLibrary, GetProcAddress) для загрузки и использования DLL.

Тип TDLLFunction определен как указатель на функцию, который представляет ссылку на процедуру в DLL:

type
  TDLLFunction = function(someParam: TSomeType): TSomeOtherType;

Функция CallDLLFunction используется для выполнения функции из DLL по имени. Она принимает три параметра:

  • dllname: имя файла DLL
  • functionname: имя функции, которую нужно выполнить
  • theParameter: параметр, который нужно передать функции

Вот пример использования этой функции:

CallDLLFunction('MYLIBRARY.dll', 'MyNewImportFunctionName', someParameter);

Код загружает DLL, получает handle к ней с помощью LoadLibrary, и затем использует GetProcAddress для получения адреса указанной функции. Если функция найдена, она вызывает функцию с предоставленным параметром. Наконец, код освобождает модуль DLL с помощью FreeLibrary.

Класс EDLLException используется для поднятия исключения, если DLL не может быть загружена или если функция не может быть выполнена.

Предложения по улучшению кода Вот несколько предложений по улучшению кода:

  1. Обработка ошибок: Код плохо обрабатывает ошибки. Например, если DLL не может быть загружена, программа будет завершаться с runtime-ошибкой. Рекомендуется использовать блоки try-except для ловли и обработки исключений.
  2. Организация кода: Код слишком длинный и сложный. Рекомендуется разбить его на более маленькие функции или классы, чтобы улучшить читаемость и поддержку.
  3. Проверка параметров: Функция CallDLLFunction не проверяет свои параметры. Рекомендуется добавить проверки, чтобы убедиться в том, что имя DLL, имя функции и параметр являются валидными перед попыткой загрузить DLL или выполнить функцию.

В целом, этот код предоставляет хороший пример динамической загрузки и использования DLL в Delphi. С некоторыми улучшениями он может быть сделан более robust и maintainable.

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


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: DLL и PlugIns ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 12:28:04/0.0061540603637695/1