ПЕРЕЛІК ДИСЦИПЛІН:
  • Адміністративне право
  • Арбітражний процес
  • Архітектура
  • Астрологія
  • Астрономія
  • Банківська справа
  • Безпека життєдіяльності
  • Біографії
  • Біологія
  • Біологія і хімія
  • Ботаніка та сільське гос-во
  • Бухгалтерський облік і аудит
  • Валютні відносини
  • Ветеринарія
  • Військова кафедра
  • Географія
  • Геодезія
  • Геологія
  • Етика
  • Держава і право
  • Цивільне право і процес
  • Діловодство
  • Гроші та кредит
  • Природничі науки
  • Журналістика
  • Екологія
  • Видавнича справа та поліграфія
  • Інвестиції
  • Іноземна мова
  • Інформатика
  • Інформатика, програмування
  • Юрист по наследству
  • Історичні особистості
  • Історія
  • Історія техніки
  • Кибернетика
  • Комунікації і зв'язок
  • Комп'ютерні науки
  • Косметологія
  • Короткий зміст творів
  • Криміналістика
  • Кримінологія
  • Криптология
  • Кулінарія
  • Культура і мистецтво
  • Культурологія
  • Російська література
  • Література і російська мова
  • Логіка
  • Логістика
  • Маркетинг
  • Математика
  • Медицина, здоров'я
  • Медичні науки
  • Міжнародне публічне право
  • Міжнародне приватне право
  • Міжнародні відносини
  • Менеджмент
  • Металургія
  • Москвоведение
  • Мовознавство
  • Музика
  • Муніципальне право
  • Податки, оподаткування
  •  
    Бесплатные рефераты
     

     

     

     

     

     

         
     
    DLL і Дельфи
         

     

    Інформатика, програмування

    DLL і Дельфи

    Думаю, багато хто знає, що таке DLL (dynamic link library - runtime). У бібліотек є чимало переваг, достатньо вагомих, що б їх використовувати. У цій статті ми навчимося створювати і використовувати динамічні бібліотеки в своїх проектах.

    Навіщо вони потрібні

    А навіщо ці самі бібліотеки мені потрібні? - Запитаєте ви. Ну я не знаю, може вони вам взагалі не потрібні. А може і життєво необхідні. Перерахую можливості і переваги бібліотек:

    Універсальність. Будь-який програміст, знаючи опису і назви функцій, що знаходяться в бібліотеці, може використовувати їх.

    Зручність налагодження. Ви можете розмістити кілька важливих функцій в бібліотеці і оголосити їх у програмі. При цьому ви будете працювати з бібліотекою, отлажівая ці функцій, не чіпаючи основну програму.

    Сховища ресурсів .. У DLL можна зберігати ресурси, такі як малюнки, форми, іконки меню, і т.д.

    Погляд на майбутнє. За допомогою бібліотек можна легко створювати плагіни, що розширюють стандартні можливості програми. Тобто можна не випускати різні версії програми, а випускати плагіни або модифіковані (наприклад з виправленими помилками) версії бібліотек.

    Спільне використання. Якщо бібліотека завантажена, то її можуть використовувати й інші додатки.

    Економія ресурсів. Бібліотеку можна завантажити і вивантажити тоді, коли це дійсно необхідно. Наприклад, програма в потрібний момент завантажила DLL, викликала функцію, зробила роботу і вивантажило бібліотеку до наступного разу. У наявності економія пам'яті

    Вобщем DLL - звір корисний і дуже навіть готовий допомогти.

    Структура динамічної бібліотеки

    Що б створити бібліотеку в Delphi6 виберіть File -> New -> Other і в вікні, що з'явилося виберіть DLL Wizard. Дельфі згенерує шаблон для бібліотеки:

    library Project;

    (Important note about DLL memory management: ShareMem must be the

    first unit in your library "s USES clause AND your project "s (select

    Project-View Source) USES clause if your DLL exports any procedures or

    functions that pass strings as parameters or function results. This

    applies to all strings passed to and from your DLL - even those that

    are nested in records and classes. ShareMem is the interface unit to

    the BORLNDMM.DLL shared memory manager, which must be deployed along

    with your DLL. To avoid using BORLNDMM.DLL, pass string information

    using PChar or ShortString parameters. )

    uses

    SysUtils,

    Classes;

    ($ R *. res)

    begin

    end.

    В коментарі вказується на необхідність вставити посилання на модуль ShareMem, якщо бібліотека експортує довгі рядки в параметрах звернення до підпрограм або як результат функцій. Це посилання має бути перша як в пропозиції uses бібліотеки, так і в uses файлу проекту програми, яка використовує цю бібліотеку. Якщо підпрограми бібліотеки експортують рядка ShortString або PChar, посилаються на ShareMem не обов'язково. Що б не виникало непорозумінь у своїх бібліотеках я рекомендую замість типу String користуватися PChar, а за необхідності конвертуйте типи функціями PChar (конветірует з String в PChar) і StrPas (конвертує з PChar в String).

    Структура бібліотеки схожа на структуру звичайного модуля. Тепер створіть бібліотеку з таким текстом:

    library Project2;

    uses

    SysUtils,

    Classes;

    function MyFunc (num1, num2, Errcode : Integer; Operation: PChar): Integer; stdcall;

    begin

    try

    if Operation = "plus" then

    Result: = num1 + num2;

    if Operation = "minus" then

    Result: = num1-num2;

    if Operation = "multiply" then

    Result: = num1 * num2;

    if Operation = "div" then

    Result: = num1 div num2;

    if Operation = "mod" then

    Result: = num1 mod num2;

    except Result: = Errcode;

    end;

    end;

    exports

    MyFunc INDEX 1 NAME "MathFunc";

    begin

    end.

    Збережіть це все куди небудь і скомпіліруйте (Ctrl + F9)

    Це буде демонстраційна бібліотека, на якій я буду показувати різні прийоми роботи з DLL. Але для початку давайте розглянемо текст цієї бібліотеки.

    function MyFunc (num1, num2, Errcode: Integer; Operation: PChar): Integer; - це звичайна функція, що повертає ціле число. Грунтуючись на параметрі Operation функція вирішує, яку операцію зробити над операндами num1 і num2. У разі помилки вона повертає переданий їй параметр Errcode. Тобто в програмі можна буде проаналізувати, чи виникла помилка під час виконання функції.

    stdcall вказує на те, що функція буде викликатися "класичним способом, тобто програми, написані на інших мовах теж зможуть користуватися бібліотекою. Можна використовувати - "register", призначеним тільки для використання програмами, написаними в середовищі Дельфі, але тоді програми, написані не в Дельфи не зможуть звертатися до цієї функції.

    exports

    MyFunc INDEX 1 NAME "MathFunc";

    Розділ Exports допомагає компілятору і компонувальника створити спеціальний заголовок DLL-модуля, в якому перераховуються імена підпрограм і адреси їхніх точок входу. У DLL може бути кілька списків Exports, але що перераховуються до них підпрограми повинні бути описані десь вище по тексту бібліотеки. Крім імені підпрограми в заголовок DLL міститься також її порядковий

    номер (INDEX), точніше, присвоєний їй цілочисельний індекс. Це дозволяє викликає програмі посилатися не на ім'я, а на індекс підпрограми і тим самим зменшити витрати часу на встановлення з нею зв'язку. Індекс присвоюється підпрограмі по порядку її появи в списках Exports: перший підпрограма в першому списку отримує індекс 0, наступна 1 і т. д.

    Програміст може змінити умовчуємо індексацію і явно вказати індекс підпрограми, додавши за її ім'ям у списку Exports слово index і ціле число в діапазоні від 0 до 32767. Крім індексу можна вказати також і довільне (NAME) ім'я функції.

    Сподіваюся, я зрозуміло пояснив;) Вобщем наша демонстраційна бібліотека готова. Тепер давайте навчимося користуватися бібліотечними функціями

    Використання бібліотечних функцій

    Використовувати функції з бібліотеки можна двома способами:

    1. Прив'язка бібліотеки до програми (статична завантаження)

    Недоліки:

    -- немає ефекту економії ресурсів (бібліотека завантажується при запуску програми і вивантажується при завершенні програми)

    -- за відсутності хоча б однієї з необхідних бібліотек в папку з програмою, або в папці $ windir $/system програма не запускається і видає повідомлення про помилку

    -- за відсутності хоча б однієї з необхідних функцій в бібліотеці під час запуску програма видає повідомлення про помилку і не запускається

    Переваги:

    -- легкість використання

    У цього способу багато недоліків. Але все ж таки він буде корисний починаючим програмістам. Для використання функцій або процедур з бібліотеки таким способом потрібно всього лише в розділі implementation вказати ім'я функції або процедури приблизно так:

    // якщо функція

    function FunctionName (Par1: Par1Type; Par2: Par2Type; ParN: ParNType): ReturnType; stdcall; external "MyDLL.dll" name "FunctionName" index FunctionIndex;

    // якщо процедура

    procedure ProcedureName (Par1: Par1Type; Par2: Par2Type; ...); stdcall; external "MyDLL.dll" name "ProcedureName" index ProcIndex;

    Розглянемо оголошення функції.

    function FunctionName (Par1: Par1Type; Par2: Par2Type; ParN: ParNType): ReturnType; - Це власне оголошення функції

    external "MyDLL.dll" ця директива вказує на ім'я бібліотеки, з якої буде викликана функція (у нашому випадку це MyDLL.dll)

    name "FunctionName" необьязательная директива, яка вказує на ім'я функції в бібліотеці; використовується для підвищення швидкості доступу до функцій (ім'я визначається всередині бібліотеки)

    index FunctionIndex теж необьязательная директива, яка використовується для прискорення доступу до функцій; вказує на індекс функції (індекс оголошує в самій бібліотеці).

    Розглядати оголошення процедури не має сенсу, тому що процедурв викликається точно так само (за винятком того, що у процедура нічого не повертає). От і все! Тепер можна користуватися обьявлений функції в межах модуля, в якому вона була об'явлена.

    Розглянемо приклад на основі нашої демонстраційної бібліотеки, яку ми скомпілював вище.

    Створити новий проект Project1 і на його форму помістіть чотири поля Edit. Дайте їм такі імена: Num1Edit, Num2Edit, OpEdit, ResultEdit. Так само помістіть одну кнопку, ім'я якої значення не має. У розділі implementation оголосити функцію:

    implementation

    function MyFunc (num1, num2, Errcode : Integer; Operation: PChar): Integer; stdcall; external "Project2.dll" name "MathFunc" index 1;

    А обробник єдиною кнопки приведіть до приблизно такого виду:

    procedure TForm1.DoItButtonClick (Sender: TObject);

    const

    Errcode : Integer = 978987;// код помилки - може бути абсолютно будь-яким.

    var

    Num1, Num2, Result_: Integer;// для перевірки чисел

    Operation : String;// операція, для передачі параметра функції

    begin

    try //перш ніж передати числа

    Num1 : = StrToInt (Num1Edit.Text);// функції перевіримо їх

    Num2: = StrToInt (Num2Edit.Text);

    except

    Num1Edit.Text: = "0";

    Num2Edit.Text: = "0";

    ResultEdit.Text: = "Введіть цілі ЧІСЛA";

    EXIT;

    end;

    Operation : = OpEdit.Text;// також перевіримо, введена чи правильна команда.

    if (Operation "plus") and (Operation "minus") and (Operation "multiply")

    and (Operation "div") and (Operation "mod") then

    begin

    ResultEdit.Text : = "Введіть коректну команду";

    Exit;

    end;

    Result_ : = MyFunc (Num1, Num2, Errcode, PChar (Operation));// використання бібліотечної функції

    if Result_ = Errcode then// якщо функція повернула код помилки то

    begin //то повідомляємо про це.

    ResultEdit.Text : = "ПОМИЛКА";

    EXIT;

    end

    else //а якщо результат відмінний від коду помилки

    ResultEdit.Text: = IntToStr (Result_);// то виводимо його

    end;

    Зверніть увагу, що ми використовуємо функцію з бібліотеки так само, як і коли вона була б написана в модулі. Ще раз повторюю, що при прив'язці бібліотеки до програми функцію можна використовувати тільки в тих модулях, в яких вона була об'явлена. Ось вам міні калькулятор, який працює на (хотів було сказати на батарейках) DLL.

    2. Динамічне завантаження

    Недоліки:

    -- громіздкість і складність коду

    -- функції бібліотеки доступні тільки тоді, коли бібліотека завантажена в пам'ять

    Переваги:

    -- начисто позбавлений всіх недоліків першого способу + деякі інші переваги перед першим способом

    Цей спосіб досить складний, особливо для новачків. Але переваг перед першим способом у нього набагато більше. Для роботи з динамічно завантажуваними бібліотеками просто необхідно знати три WinAPI функції: LoadLibrary, GetProcAddress І FreeLibrary.

    LoadLibrary (LibFileName: PChar) - завантажує бібліотеку LibFileName в пам'ять. Якщо бібліотека завантажена вдало, то функція повертає дескриптор (THandle) DLL в пам'яті.

    GetProcAddress (Module: THandle; ProcName: PChar) - знаходить точку входу у функцію ProcName. Увага! Тут потрібно вказати NAME функції, а не її назва. Якщо функція знайдено, то функція GetProcAddress повертає дескриптор (TFarProc) функції в завантаженої DLL.

    FreeLibrary (LibModule: THandle) - вивантажує бібліотеку LibModule. При цьому вся зайнята цієї бібліотекою пам'ять звільняється. Слід зауважити, що після виклику цієї процедури функції даної бібліотеки більше і було звернення до них викличе виняток.

    Для того, що б динамічно завантажити функцію з бібліотеки, то необхідно її оголосити у роздiлi var:

    MyFunc: function (num1, num2, Errcode : Integer; Operation: PChar): Integer; stdcall;

    Також потрібно оголосити змінну типу THandle. "На пальцях" не обьяснить, тому давайте розглянемо приклад динамічної завантаження DLL на основі нашої демонстраційної бібліотеки.

    Відкрийте попередній проект з демонстрацією статичної завантаження. У розділі var оголосити пару нових змінних:

    LibHandle: THandle;

    MyFunc: function (num1, num2, Errcode : Integer; Operation: PChar): Integer; stdcall;

    Оброблювач кнопки приведіть до такого виду:

    procedure TForm1.DoItButtonClick (Sender: TObject);

    const

    Errcode : Integer = 978987;// код помилки - може бути абсолютно будь-яким.

    var

    Num1, Num2, Result_: Integer;// для перевірки чисел

    Operation : String;// операція, для передачі параметра функції

    begin

    try //перш ніж передати числа

    Num1 : = StrToInt (Num1Edit.Text);// функції перевіримо їх

    Num2: = StrToInt (Num2Edit.Text);

    except

    Num1Edit.Text: = "0";

    Num2Edit.Text: = "0";

    ResultEdit.Text: = "Введіть ЧІСЛA";

    EXIT;

    end;

    Operation : = OpEdit.Text;// також перевіримо, введена чи правильна команда.

    if (Operation "plus") and (Operation "minus") and (Operation "multiply")

    and (Operation "div") and (Operation "mod") then

    begin

    ResultEdit.Text : = "Введіть коректну команду";

    Exit;

    end;

    // до цього моменту код залишився без змін.

    @ MyFunc : = Nil;// очищаємо адреса функції

    LibHandle : = LoadLibrary ( "Project2.dll ");// намагаємося завантажити бібліотеку

    if LibHandle> = 32 then

    begin //якщо все пройшло успішно то

    @ MyFunc : = GetProcAddress (LibHandle, "MathFunc ");// намагаємося знайти адресу функції

    if @ MyFunc nil then// якщо адреса знайдений (функція існує в бібліотеці)

    Result_ : = MyFunc (Num1, Num2, Errcode, PChar (Operation));// використання бібліотечної функції

    if Result_ = Errcode then// якщо функція повернула код помилки то

    begin //то повідомляємо про це.

    ResultEdit.Text : = "ПОМИЛКА";

    EXIT;

    end

    else //а якщо результат відмінний від коду помилки

    ResultEdit.Text: = IntToStr (Result_);// то виводимо його)

    end;

    end;

    Висновок

    В цій статті ми торкнулися лише основних аспектів програмування із застосуванням динамічно-підключаються бібліотек. Але ж в DLL можна зберігати всякі картинки і навіть форми! За допомогою них зручно створювати всякі плагіни. Але це вже зовсім інша історія

    Список літератури

    Для підготовки даної роботи були використані матеріали з сайту http://www.soch.imperium.by

         
     
         
    Реферат Банк
     
    Рефераты
     
    Бесплатные рефераты
     

     

     

     

     

     

     

     
     
     
      Все права защищены. Reff.net.ua - українські реферати ! DMCA.com Protection Status