Иногда бывает полезно знать какими DLL-ками пользуется Ваше приложение. Давайте посмотрим как это можно сделать:

Автор: Simon Carter 

Пример функции

Код, представленный ниже демонстрирует простейшую DLL с всего одной функцией "TestDLL". Результат этой процедуры - диалоговое окошко с текстом.

 DLL возможно загружать двумя способами:

 

- статически

- динамически

  

Давайте создадим простую библиотеку DLL:

 

Project file name: c:\example\exdouble\exdouble.dpr

Данная функция определяет присутствие нужной функции в библиотеке (dll) и, в случае нахождения искомой функции возвращает True, иначе False.

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

вопросы разработки и использования DLL в Borland Delphi. Для новых подписчиков сообщаю,

что первую часть статьи они могут посмотреть в архиве рассылки, выпуск номер 13.

Прошу прощения у тех, кто писал мне, но не получил ответа. В ближайшее время постараюсь это исправить.

 

Итак, продолжим.

 

Создайте и откомпилируйте пустой проект DLL, который содержит ссылку на файл ресурсов .res, который содержит Ваши ресурсы.

Вы должны определить в программе вызываемую снаружи функцию.

 

Функция должна быть __stdcall (или WINAPI, что то же самое ;)) и иметь

четыре аргумента. Первый - HWND окна, порождаемого rundll32 (можно

использовать в качестве owner'а своих dialog box'ов), второй - HINSTANCE

задачи, третий - остаток командной строки (LPCSTR, даже под NT),

четвертый - не знаю ;).

 

Code:

procedure GetFileVersion(FileName: string; var Major1, Major2,

   Minor1, Minor2: Integer);

var

   Info: Pointer;

   InfoSize: DWORD;

   FileInfo: PVSFixedFileInfo;

   FileInfoSize: DWORD;

   Tmp: DWORD;

begin

   InfoSize := GetFileVersionInfoSize(PChar(FileName), Tmp);

   if InfoSize = 0 then

     //Файл не содержит информации о версии

   else

   begin    

     GetMem(Info, InfoSize);

     try

       GetFileVersionInfo(PChar(FileName), 0, InfoSize, Info);

       VerQueryValue(Info, '\', Pointer(FileInfo), FileInfoSize);

       Major1 := FileInfo.dwFileVersionMS shr 16;

       Major2 := FileInfo.dwFileVersionMS and $FFFF;

       Minor1 := FileInfo.dwFileVersionLS shr 16;

       Minor2 := FileInfo.dwFileVersionLS and $FFFF;

     finally

       FreeMem(Info, FileInfoSize);

     end;

   end;

end;

 

При объявлении процедур и функций в динамических библиотеках используются различные соглашения о вызовах. Дело в том, что различные языки программирования по-разному реализуют передачу параметров в процедуру (через стек или регистры). Порядок следования параметров в стеке как раз определяется соглашением о вызовах.

 

Стандартный вызов в языках C++ и Object Pascal различается, но набор директив смены типа вызова позволяет обеспечить любую реализацию.

 

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

 

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

Code:

uses Windows;

 

procedure ShowDllPath stdcall;

var

TheFileName : array[0..MAX_PATH] of char;

begin

FillChar(TheFileName, sizeof(TheFileName), #0);

GetModuleFileName(hInstance, TheFileName, sizeof(TheFileName));

MessageBox(0, TheFileName, 'The DLL file name is:', mb_ok);

end;

 

Если динамическая библиотека в процессе работы использует переменные или функции, осуществляющие динамическое выделение памяти под собственные нужды (длинные строки, динамические массивы, функции New и GetMem), а также, если такие переменные передаются в параметрах и возвращаются в результатах, то в таких библиотеках обязательно должен использоваться модуль ShareMem. При этом в секции uses модуль должен располагаться на первом месте. Об этом напоминает комментарий, автоматически добавляемый в файл динамической библиотеки при создании.

 

Управление этими операциями осуществляет специальный диспетчер печати BORLANDMM.DLL. Он должен распространяться вместе с динамическими библиотеками, использующими модуль ShareMem.