Dll і повторне використання коду розділяй і спрощуй

DLL і повторне використання коду: Розділяй і спрощуй

Jeffrey Slarve

Багато років тому, коли я був відносним новачком в Clarion for Windows (думаю що це була версія 1.0), я запам'ятав читання есе Dave Harms- а про поділ додаток на кілька DLL. Це був для мене великий скачок в розумінні того чому поділ додаток є доброю справою, як елементарно просто це робиться, і як прискорюється при цьому процес розробки. Використання DLL дозволяє мені працювати з невеликими шматками проекту без необхідності перекомпілювати все додаток після будь-якого невеликого зміни / тесту, яке мені потрібно зробити. Все в світі було блаженно і я жив після цього щасливо. Кінець.

Добре, не зовсім кінець. Минув час, я писав проект за проектом (проект в даному випадку означає все компоненти програми), і помітив що мені доводиться повторювати один і той же код в кожному проекті. Більшість цих функцій були досить універсальними і не пов'язані з Dictionary. Тому я спробував зробити загальну DLL. якої не потрібна Dictionary і інші глобальні дані, але Application Generator порахував що він розумніший за мене (що, насправді, цілком може бути). AppGen генерує пачку глобальних змінних (GlobalRequest, GlobalResponse і т..п.) Або як External або як локальні. Якщо глобальні дані локальні, то це означає що місце для них виділяється в DLL. шаблони генерує файл .EXP і включають в нього ці глобальні змінні, що призводить до помилки дублювання імен при складанні проекту. Якщо я спробую зробити ці глобальні дані External. то всі мої глобальні змінні, які я використовую в цій DLL, стають доступними в будь-якому проекті, що використовує цю загальну DLL.

Спочатку я намагався обдурити AppGen. використовуючи локальні змінні і модифікуючи EXP- файл після генерації коду, але це виявилося занадто складно. Особливо коли з'явився ABC з його глобальними деклараціями класів.

Але в чому справа! Що я тепер збираюся робити. Іншим варіантом є створення DLL "вручну". Це здається занадто складним, але я пам'ятав що цей код змінюється дуже рідко, тому ефект полягає в тому що зробити це потрібно тільки один раз і заодно навчитися це робити. Крім цього, я отримаю багато переваг як упущу мої часто використовувані універсальні функції в окрему DLL:

1. Повторне використання коду. Більше не потрібно переписувати або імпортувати функцію DayOfWeek (). або функцію отримання widget from a dofladgey. Потрібно тільки підключити цю DLL до додатка і готово.

2. Написати один раз. і виправляти в одному місці. Якщо в потрібно зробити будь-яке зміна в загальній функції, то його можна буде зробити тільки в одному місці. Часто, додаток використовує таку DLL не потрібно навіть перекомпіліровать. Перекомпіліровать доведеться тільки в наступних ситуаціях:

а) Чи змінився один із прототипів. Якщо змінився прототип будь-якої функції DLL. то програма не зможе знайти цю процедуру якщо його не перекомпіліровать.
  • б) Додані нові процедури. Зазвичай не потрібно перекомпілювати додаток, якщо були додані нові функції в DLL. Звичайно, якщо в додатку потрібно використовувати ці нові функції, то його доведеться перекомпілювати.
  • в) Нова версія Clarion. Не можна нормально використовувати DLL. яка скомпільована на іншою версією Clarion. Звичайно, ви можете це зробити, але за допомогою спеціальних знань або інструментів. Краще перекомпіліровать.







  • 3) Легкість підтримки. Коли DLL зроблена один раз, то робити в ній зміни дуже просто. Це набагато легше ніж намагатися робити зміни в тій же самій функції DayOfWeek () в 20-і місцях.

    4) Coolness. DLL- це дуже кльово. Насправді - дуже дуже cool.


    Ручне створення DLL

    Є кілька речей, які потрібно зробити для ручного створення DLL. Деякі з них можуть здатися не знайомими для тих хто поки не стикався з цим аспектом програмування, але насправді вони не складні коли розберешся. Ось ці кроки:

    1. Створити каталог
    2. Створити PRJ- файл
    3. Створити файл (файли) вихідного тексту
    4. Створити EXP- файл
    5. Скомпілювати DLL
    6. Зробити доступними прототипи процедур DLL
    7. Зробити DLL доступною для всіх додатків
    8. Використовувати DLL

    Першим кроком є ​​створення каталогу де-небудь в дереві каталогів проектів Clarion. Це хороша ідея - тримати в одному місці все його компоненти.

    Створити PRJ- файл

    PRJ - файл або Project - це татко (або якщо хочете, мамочка) башей DLL. Потрібно знати все з чого складається ваша DLL. включаючи драйвери файлів, зовнішні бібліотеки, значки (icons). і вихідні тексти. Без проекту, я не знаю що потрібно робити. Може рибалити або грати на гітарі.







    Створити PRJ- файл дуже легко в Clarion IDE:

    а) Натиснути File | New і вибрати Project
    б) У який з'явився файловому діалозі потрібно ввести ім'я вашого нового проекту. Воно може збігатися або не збігатися з ім'ям DLL. Натиснути Save.
    в) Тепер ви повинні побачити вікно з ім'ям New Project File. В цьому вікні можна:
    i. Введіть назву проекту. Це поле не обов'язкова.
    ii. Main File - це ім'я головного CLW- файлу вашого проекту. Просто введіть тут ім'я і натисніть до лавішу Tab .Це не обов'язково має бути ім'я вже існуючого файлу.
    iii. Target File буде мабуть збігатися з ім'ям Main File. крім розширення EXE. Воно зміниться на DLL. після того як ви зміните Target Type на DLL. Натисніть OK.
    г) Ви тільки що створили проект. Якщо це ваш перший проект, то вітаю.

    Ви могли помітити, що є ще один Target Type з ім'ям Library. Бібліотеки дуже схожі на DLL. але вони мають переваги і недоліки в порівнянні з DLL. Я вважаю за краще використовувати DLL через те, що вони легше справляються, і набагато рідше вимагають повної перекомпіляції всього програми. Якщо зробити будь-яка зміна в LIB. то доведеться перекомпілювати (як мінімум облінкований) всі програми, які використовують цю LIB. Єдиний недолік DLL полягає в тому що додається ще один файл в поставку програми. Правда, зазвичай це є перевагою, так як при зміні DLL вам буде потрібно розіслати лише один цей файл.

    Створити файл (файли) вихідного тексту

    Це місце де будуть знаходитися ваші функції / процедури. Для цілей цієї статті я використовую одну з функцій мого сайту ClarionFAQ.com. Ця функція використовується для переміщення у вікні батьківського контрола (Group, Option і т.п.) разом з його "дочірніми" контроль. Якщо ви коли-небудь намагалися переміщати такий контрол в runtime. то ви знаєте, що дочірні контроли не мають ніякого поняття про те куди переміщається їх батько.

    Далі перераховано мінімум того що потрібно помістити в головний модуль і східного коду DLL щоб він компілювався.

    а) Оператор PROGRAM або MEMBER. Хоча DLL не є програмою, але компілятору вони потрібні все одно. Якщо ви використовуєте оператор MEMBER. то переконаєтеся що він не має будь-яких параметрів. Він повинен знаходитися на першому рядку де-небудь далі першої колонки.
    б) Оператор MAP. Тут ви ставите прототипи функцій, які ви використовуєте і експортувати в DLL.

    map
    JSMoveParentControl (Long pParentFEQ, Long pXShift, Long pYShift, Byte pMoveType = 0)
    end

    в) Секція CODE. Тут ви пишіть код. Дивіться в доданому файлі mydll.clw як це буде все разом.

    Створити EXP- файл

    Файл EXP або файл експорту і визначення модуля використовується для того щоб повідомити проекту які змінні і функції повинні бути експортовані для інших додатків, що використовують DLL. Деякі функції можуть використовуватися тільки в інших функціях вашої DLL. і тоді їх не потрібно експортувати. Файл EXP може бути дуже складним або простим, але в будь-якому випадку це просто текстовий файл. Хелп по Clarion 6 містить багато інформації по EXP- файлів, але можливо її складно знайти. Просто пошукайте .EXP і потім дивіться Module Definition Files.

    Ось як виглядає EXP- файл нашої невеликої DLL:

    NAME 'MYDLL' GUI
    EXPORTS
    JSMOVEPARENTCONTROL @ FlllUc @?
    Обов'язково додайте в кінці порожній рядок!

    Зверніть увагу на рядок JSMOVEPARENTCONTROL @ FlllUc. Ви бачите що вона не схожа на оригінальний прототип функції JSMoveParentControl (). Ви запитаєте, чому. Я не знаю. І не думаю що будь-хто знає. Це просто працює. Це називається Name Mangling. Воно дозволяє робити перевантаження імен процедур. Name Mangling можна відключити якщо використовувати атрибут Name () процедури, і це може добре працювати в більшості випадків, але не дуже складно самостійно робити Mangling. На щастя, з Clarion- му поставляється приклад програми (% CWROOT% \ Examples \ Src \ Pro2exp) для цього. Просто скомпілюйте цю програму, введіть ваш прототип в її поле введення і натисніть TAB. Pro2exp покаже ваш mangled прототип.

    ПРИМІТКА: Звернули увагу на пропозицію про порожній лінії після останнього рядка EXP- файлу. Це дуже важливо, і я витратив на це годинник коли писав цю статтю. До того як я додав цей рядок IDE (C5.5) "падала" і не експортувала мою функцію при остаточному складанні DLL.

    Добре. Натисніть на цю кнопку з блискавкою і дайте їй спалахнути. На щастя, як і у мене, перший раз у вас все скомпілювати без помилок. Ха-ха. Добре. нарешті скомпілювати. І що. Після успішної компіляції проекту DLL. ви отримаєте DLL- і LIB- файли. LIB- файл це "клей" для з'єднання вашої DLL з додатком. Він міститься в проект програми, з якою буде використовувати вашу DLL. Коли ви приєднуєте DLL до додатка таким способом, вам потрібно помістити DLL в місце, де її зможе знайти додаток. (Дивіться також три статті Larry Sand) про завантаження DLL під час виконання.

    Зробити доступними прототипи процедур DLL

    Я зазвичай створюю include- файл, призначений для включення в додатки, тому в додатку мені не потрібно нічого вводити для того щоб зробити функції доступними. Просто скопіюйте секцію MAP в окремий файл. Прямо зараз.


    Зробити DLL доступною для всіх додатків

    Ну тепер у вас є DLL і ви напевно збираєтеся її використовувати. Я припускаю що у вас є зайва фантазія і ви можете написати шаблон, який підключає DLL до додатка. Але це так просто зробити, що я не зв'язуюся через це з шаблонами. Ось все що потрібно зробити:

    1. Відкрийте App. куди потрібно додати DLL
    2. Натисніть вкладку Module
    3. Натисніть меню Application і виберіть Insert Module. З'явиться вікно Select Module Type.
    4. Виберіть в цьому вікні External DLL
    5. У поле Name введіть ім'я вашої DLL з розширенням LIB
    6. У полі Map Include File введіть ім'я вашого include- файлу

    ЗАУВАЖЕННЯ: Якщо ви будете використовувати include- файл. то процедури DLL НЕ будуть автоматично видно в AppGen. хоча ви можете їх використовувати в embed- ах. Е то розчаровує якщо ви не знаєте про це. Якщо вам потрібно зробити процедури видимими в AppGen. то їх доведеться ввести вручну як External (або експортувати з іншого App) замість використання inc- фала. Виберіть модуль DLL. натисніть Insert або виберіть Procedure | New і створіть процедуру з правильним прототипом. Може також знадобитися включити ознака Declare Globally в описі процедури.

    Carl Barns написав utility- шаблон, який використовує функцію LinkName () з мови шаблонів Clarion. Файл CBMangle.zip містить шаблон і приклади вхідного і вихідного файлів. Перевага використання цього шаблону для формування EXP- файлу полягає в тому, що функція LinkName () має найбільш коректну логіку для обробки нововведень в мові. Спасибі Carl.