PODSTAWY PROGRAMOWANIA

Podobne dokumenty
Język programowania DELPHI / Andrzej Marciniak. Poznań, Spis treści

Tworzenie własnych komponentów

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

PODSTAWY PROGRAMOWANIA

Typy klasowe (klasy) 1. Programowanie obiektowe. 2. Założenia paradygmatu obiektowego:

Delphi Laboratorium 3

Zaawansowane programowanie w (pakiecie) Delphi

Pascal typy danych. Typy pascalowe. Zmienna i typ. Podział typów danych:

Kurs WWW. Paweł Rajba.

PODSTAWY PROGRAMOWANIA

PODSTAWY PROGRAMOWANIA

Wykład 8: klasy cz. 4

DIAGRAMY SYNTAKTYCZNE JĘZYKA TURBO PASCAL 6.0

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat

Podstawy programowania skrót z wykładów:

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Podstawy Programowania semestr drugi. Wykład czternasty

Wprowadzenie do systemu Delphi

Ada-95. Dariusz Wawrzyniak

TEMAT : KLASY DZIEDZICZENIE

PODSTAWY PROGRAMOWANIA

Programowanie obiektowe

Język programowania. Andrzej Bobyk

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

PHP 5 język obiektowy

PODSTAWY PROGRAMOWANIA

Język programowania PASCAL

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Komunikacja i wymiana danych

Zapis programu z wykorzystaniem modułu (Podstawy Delphi 2.1, 2.2, 2.3 str11 )

Wykład 5 Okna MDI i SDI, dziedziczenie

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

OPERACJE NA PLIKACH. Podstawowe pojęcia:

PODSTAWY PROGRAMOWANIA

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Informatyka I. Dziedziczenie. Nadpisanie metod. Klasy abstrakcyjne. Wskaźnik this. Metody i pola statyczne. dr inż. Andrzej Czerepicki

Wykład 7: Pakiety i Interfejsy

Podstawy Programowania C++

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Programowanie RAD Delphi

Jeśli chcesz łatwo i szybko opanować podstawy C++, sięgnij po tę książkę.

Wykład 5: Klasy cz. 3

Rozdział 4 KLASY, OBIEKTY, METODY

Podstawy programowania. Wykład PASCAL. Zmienne wskaźnikowe i dynamiczne. dr Artur Bartoszewski - Podstawy prograowania, sem.

Programowanie obiektowe

Wykład 15. Literatura. Kompilatory. Elementarne różnice. Preprocesor. Słowa kluczowe

Podstawy Programowania 2

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Wykład 4. Tablice. Pliki

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Wyrażenie include(sciezka_do_pliku) pozwala na załadowanie (wnętrza) pliku do skryptu php. Plik ten może zawierać wszystko, co może się znaleźć w

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Programowanie w języku Python. Grażyna Koba

PARADYGMATY PROGRAMOWANIA Wykład 4

Delphi podstawy programowania. Środowisko Delphi

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Budowa i oprogramowanie komputerowych systemów sterowania. Laboratorium 4. Metody wymiany danych w systemach automatyki DDE

Tablice. Jones Stygar na tropie zmiennych

Materiały do laboratorium MS ACCESS BASIC

Tabela wewnętrzna - definicja

Szablony klas, zastosowanie szablonów w programach

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Klasy cd. Struktury Interfejsy Wyjątki

Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody

Programowanie obiektowe

.NET Klasy, obiekty. ciąg dalszy

Nazwa implementacji: Kółko i krzyżyk w Lazarusie. Autor: Piotr Fiorek Andrzej Stefaniuk

Lab 9 Podstawy Programowania

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Programowanie obiektowe

Wstęp do programowania. Różne różności

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Wstęp do programowania. Wykład 1

Programowanie obiektowe

Programowanie obiektowe. Obiekt Klasa Składnia klasy: Interfejsy Składnia interfejsu: Metody Składnia instrukcji Sub: Składnia instrukcji function:

Wykład 4: Klasy i Metody

Swift (pol. jerzyk) nowy język programowania zaprezentowany latem 2014 r. (prace od 2010 r.)

PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec

PHP: bloki kodu, tablice, obiekty i formularze

Programowanie obiektowe

Pascal - wprowadzenie

Wstęp do programowania. Procedury i funkcje. Piotr Chrząstowski-Wachtel

Mikroprocesor Operacje wejścia / wyjścia

Programowanie w Turbo Pascal

Wstęp do programowania 2

Różne właściwości. Różne właściwości. Różne właściwości. C++ - klasy. C++ - klasy C++ - KLASY

Podstawy programowania. Wykład 6 Wskaźniki. Krzysztof Banaś Podstawy programowania 1

Delphi 7 + Indy 10 Przykłady prostych aplikacji sieciowych

Procedury i funkcje - powtórzenie i uzupełnienia. Przykład funkcji potęgowanie przy wykładniku naturalnym

Zaawansowane programowanie w języku C++ Klasy w C++

Co to jest klasa? Z programistycznego punktu widzenia klasa stanowi typ danych, który odwzorowuje wspólne cechy jakiegoś obiektu.

Pola i metody statyczne. Klasy zawierające pola i metody statyczne

Wykład 2 Składnia języka C# (cz. 1)

PROGRAM: WYSZUKANIE LICZBY MAKSYMALNEJ

Dziedziczenie jednobazowe, poliformizm

Programowanie obiektowe

Multimedia JAVA. Historia

Aplikacje w środowisku VBA. Visual Basic for Aplications

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

Transkrypt:

PODSTAWY PROGRAMOWANIA Andrzej Marciniak Prezentacja multimedialna przygotowana za pomocą systemu Corel Presentations X3 Copyright 2003-2017 by Andrzej Marciniak PP-9(1 z 85)

Na poprzednim wykładzie... P funkcje i procedury (cd.) przeciążanie funkcji i procedur przykłady definicji funkcji i procedur wywołanie funkcji i procedury konwencje wywoływania funkcji i procedur oraz dyrektywa inline funkcje i procedury anonimowe funkcje i procedury asemblerowe podprogramy zewnętrzne P przetwarzanie obiektów definicje metod konstruktory i destruktory metody statyczne, wirtualne, dynamiczne i abstrakcyjne przeciążanie metod PP-9(2 z 85)

Na tym wykładzie... P przetwarzanie obiektów (cd.) obsługa wiadomości własności własności tablicowe specyfikacje opcjonalne w deklaracjach własności pokrywanie własności własności klasowe Płącza programowe Pdodatkowe informacje o modułach części inicjująca i finalizująca moduły wzajemnie zależne P biblioteki łączone dynamicznie dostęp do funkcji i procedur moduły importowe importowanie statyczne i dynamiczne tworzenie bibliotek DLL PP-9(3 z 85)

Przetwarzanie obiektów Obsługa wiadomości Obsługa i działanie środowiska Windows (oraz uruchamianych w nim programów) opiera się na zdarzeniach. Oznacza to, że każdy sygnał wejściowy pochodzący od użytkownika (na przykład naciśnięcie klawisza myszki lub klawiatury) jest interpretowany jako zdarzenie, dla którego środowisko Windows generuje odpowiednią wiadomość. PP-9(4 z 85)

Przetwarzanie obiektów Obsługa wiadomości Wiadomości środowiska Windows są identyfikowane za pomocą stałych, a przesyłane w rekordach o ogólnym typie TMessage (w module Winapi.Messages): type PMessage = ^TMessage; TMessage = packed record Msg : Cardinal; case Integer of 0 : (WParam : LongInt; LParam : LongInt; Result : LongInt); 1 : (WParamLo : Word; dotyczy procesora 64-bitowego i umożliwia dostęp do każdego bajta end; WParamHi : Word; WParamFiller : TDWordFiller; LParamLo : Word; LParamHi : Word; LParamFiller : TDWordFiller; ResultLo : Word; ResultHi : Word); ResultFiller : TDWordFiller; Pole Msg służy do przechowywania identyfikatora wiadomości, pola WParam oraz LParam są przeznaczone do przesyłania dodatkowych informacji związanych z daną wiadomością, a pole Result służy do przekazywania informacji po obsłużeniu wiadomości. PP-9(5 z 85)

Przetwarzanie obiektów Obsługa wiadomości Metoda służąca do obsługi wiadomości powinna być zadeklarowana w sekcji private definicji typu klasowego i musi być metodą-procedurą (nie może być metodą-funkcją). Deklaracja takiej metody zawiera dyrektywę języka message, po której występuje stała całkowita o wartości od 1 do 49151. Na ogół stałej tej nie podaje się w postaci liczby całkowitej, lecz określa się za pomocą identyfikatora (wygodnie jest określić identyfikator, którego nazwa kojarzy się z obsługiwaną wiadomością). PP-9(6 z 85)

Przykład Przetwarzanie obiektów Obsługa wiadomości Przypuśćmy, że zamierzamy napisać własną metodę obsługi zdarzenia polegającego na zmianie rozmiaru głównego okienka programu. Wiadomość związana z tym zdarzeniem jest w środowisku Windows identyfikowana stałą WM_SIZE. Deklaracja odpowiedniej metody może być następująca: type TOknoGlowne = class (TForm)... private procedure WMSize (var wiadomosc : TWMSize); message WM_SIZE;... PP-9(7 z 85) end;

Przetwarzanie obiektów Obsługa wiadomości Definicja metody obsługującej wiadomość ma postać taką samą, jak definicja każdej innej metody. Opcjonalnie może ona zawierać instrukcję dziedziczenia składającą się z samego słowa kluczowego inherited. Wystąpienie tej instrukcji powoduje przekazanie rekordu z wiadomością (określonego przez parametr) do metody dziedziczonej. Jeżeli w żadnym z nadrzędnych typów klasowych nie określono metody obsługującej daną wiadomość, to nastąpi wywołanie metody DefaultHandler, która jest zdefiniowana w typie TObject. PP-9(8 z 85)

Przykład Przetwarzanie obiektów Obsługa wiadomości Szkielet definicji metody zadeklarowanej w poprzednim przykładzie może być następujący: procedure TOknoGlowne.WMSize (var wiadomosc : TWMSize); begin if warunek then... else inherited end; lub PP-9(9 z 85)

Przykład Przetwarzanie obiektów Obsługa wiadomości Szkielet definicji metody zadeklarowanej w poprzednim przykładzie może być następujący: procedure TOknoGlowne.WMSize (var wiadomosc : TWMSize); begin instrukcje inherited end; PP-9(10 z 85)

Przetwarzanie obiektów Obsługa wiadomości Metody obsługujące wiadomości nie są wywoływane bezpośrednio, ale za pomocą metody-procedury Dispatch typu klasowego TObject, która wysyła odpowiednie wiadomości. Wywołanie metody Dispatch ma postać Dispatch (wiadomość) gdzie wiadomość oznacza rekord (dokładniej: zmienną nieokreślonego typu), którego pierwsze pole (cztery bajty) powinno być typu Cardinal. Wartość tego pola identyfikuje wysyłaną wiadomość (należy mu przypisać stałą oznaczającą daną wiadomość). Pozostałe pola rekodu mogą zawierać informacje specyficzne dla przetwarzanej wiadomości. PP-9(11 z 85)

Przetwarzanie obiektów Własności Własności (cechy) są rozszerzeniem pojęcia pola obiektu. Podobnie jak pola, mogą służyć do przechowywania różnych wartości (atrybutów) obiektu, ale dodatkowo umożliwiają wykonanie różnych operacji podczas ich odczytu i zapisu. Deklaracja każdej własności określa jej nazwę i typ oraz operacje związane z jej odczytem i zapisem (poprzez wskazanie na odpowiednie metody). PP-9(12 z 85)

Przykład Przetwarzanie obiektów Własności type komponent = class (TComponent)... inne deklaracje private pole_licznik : Word; function odczytaj_licznik : Word; procedure ustal_licznik (wartosc : Word); public property licznik : Word read odczytaj_licznik write ustal_licznik;... inne deklaracje end; PP-9(13 z 85)

Przetwarzanie obiektów Własności W języku Delphi nie nałożono żadnych ograniczeń na sposób przechowywania wartości własności. Zaleca się jednak stosowanie koncepcji przyjętej dla komponentów biblioteki VCL, tj.: P przechowywanie wartości własności w polach typu klasowego (zdefiniowanych w tym samym typie co własności), P oznaczanie identyfikatorów pól przechowujących wartości własności od początkowej litery F (np. dla własności o nazwie Temperatura pole służące do przechowywania jej wartości powinno nazywać się FTemperatura), P deklarowanie pól przechowujących wartości własności w sekcji private (zapewnia to dostęp do tych pól przez komponent zawierający deklaracje własności, ale nie przez inne komponenty, w tym komponenty potomne). PP-9(14 z 85)

Przetwarzanie obiektów Własności Dostęp do wartości (zapis i odczyt wartości) własności może być bezpośredni lub pośredni za pomocą specjalnych metod. Z dostępem bezpośrednim mamy do czynienia wówczas, gdy w deklaracji własności po słowie read i write występuje nazwa odpowiedniego pola (miejsca przechowywania wartości własności). PP-9(15 z 85)

Przykład Przetwarzanie obiektów Własności Załóżmy, że w sekcji private pewnego typu klasowego zadeklarowano pole FLicznik typu Integer. Bezpośredni dostęp do wartości własności Licznik zapewni następująca jej deklaracja (w sekcji published, gdy wartość ma być wyświetlana w okienku Object Inspector): property Licznik : Integer read FLicznik write FLicznik; PP-9(16 z 85)

Przetwarzanie obiektów Własności W przypadku dostępu pośredniego do wartości własności w jej deklaracji po słowach read i write specyfikowane są metody dostępu. Dla komponentów biblioteki VCL przyjęto zasadę, że metody odczytu wartości własności o nazwie XXX mają nazwę GetXXX, a metody zapisu (ustalania wartości) SetXXX. Oprócz dostępu bezpośredniego i pośredniego można też zastosować połączenie obu sposobów dostępu i na przykład przy odczycie stosować dostęp bezpośredni, a przy zapisie pośredni. PP-9(17 z 85)

Przetwarzanie obiektów Przykład Własności type TTermometr = class (TControl)... inne deklaracje private FTemperatura : temp_celsjusza; procedure SetTemperatura (wartosc : temp_celsjusza); published property Temperatura : temp_celsjusza read FTemperatura write SetTemperatura;... inne deklaracje end; PP-9(18 z 85)

Przetwarzanie obiektów Własności tablicowe Własności tablicowe służą do opisu własności indeksowanych, które mogą zawierać wiele wartości odpowiadających poszczególnym wartościom indeksu. W deklaracji własności tablicowej po nazwie własności (ale przed określeniem typu) występuje lista parametrów ujęta w nawiasy kwadratowe. Przykłady property Punkt [x, y : Integer] : TPoint read GetPunkt write SetPunkt; property Lancuch [const nazwa : string] : string read GetLancuch write SetLancuch; PP-9(19 z 85)

Przetwarzanie obiektów Własności tablicowe Postać listy parametrów jest taka sama, jak w definicji funkcji i procedury. Parametry (indeksy) mogą być dowolnych typów (nie tylko typów porządkowych, jak w przypadku indeksów tablic). Dla własności tablicowych można stosować wyłącznie dostęp pośredni. Ponadto metoda określona po słowie read musi być funkcją, która ma taką samą liczbę parametrów o takich samych typach, jak w liście określającej indeksy. Typ wartości tej funkcji powinien być przy tym identyczny z typem własności. Z kolei metoda zapisu (określona po słowie write) musi być procedurą, której lista parametrów zawiera parametry o identycznym typie, jak w liście indeksów własności oraz dodatkowo jeden parametr przekazywany przez wartość lub stałą określonego typu, którego typ jest identyczny z typem własności. PP-9(20 z 85)

Przetwarzanie obiektów Własności tablicowe Deklaracja własności tablicowej może być zakończona dyrektywą języka default. Jej wyspecyfikowanie oznacza, że dana własność jest domyślną własnością klasy, przy czym w obrębie jednej definicji typu klasowego tylko jedna własność może być domyślna, a typy potomne nie mogą jej ani zmienić, ani pokryć. Do domyślnych własności tablicowych można odwoływać się bez specyfikowania jej nazwy (wystarczy podać nazwę obiektu danego typu klasowego i ujęty w nawiasy kwadratowe indeks). PP-9(21 z 85)

Przetwarzanie obiektów Własności tablicowe Przykład type klasa =class... inne deklaracje public property Lancuchy [const indeks : Integer] : string read GetLancuch write SetLancuch; default;... inne deklaracje end; Po zadeklarowaniu zmiennej: var obiekt : klasa; odwołanie obiekt.lancuchy[4] będzie można skrócić do postaci obiekt[4]. PP-9(22 z 85)

Przetwarzanie obiektów Specyfikacje opcjonalne w deklaracjach własności W deklaracjach własności można dodatkowo wyspecyfikować dyrektywy języka index, default, nodefault, stored i implements. Ostatnia dyrektywa dotyczy klas implementujących łącza programowe (będzie dalej). Dyrektywa index postaci index stała-całkowita umożliwia określenie dla wielu własności tych samych metod dostępu. Specyfikuje się ją po identyfikatorze typu własności. W metodach dostępu własności z dyrektywą index należy dodać jeden parametr typu Integer. Dla metody-funkcji, która odczytuje wartość własności powinien to być ostatni parametr, a dla metody-procedury zapisującej wartość własności przedostatni (poprzedzający bezpośrednio parametr ustalający wartość własności). PP-9(23 z 85)

Przetwarzanie obiektów Specyfikacje opcjonalne w deklaracjach własności Przykład type TTermometr = class (TControl)... inne deklaracje private FTemperatura : array [0..1] of temp_celsjusza; function GetTemperatura (indeks : Integer) : temp_celsjusza; procedure SetTemperatura (indeks : Integer; temp : temp_celsjusza); published property TempGodz12 : temp_celsjusza index 0 read GetTemperatura write SetTemperatura; property TempGodz24 : temp_celsjusza index 1 read GetTemperatura write SetTemperatura; property Temperatura [indeks : Integer] : temp_celsjusza read GetTemperatura write SetTemperatura;... inne deklaracje end; Po zadeklarowaniu zmiennej obiektowej temperatura powyższego typu instrukcje temperatura.tempgodz24:=temperatura.tempgodz12+10; i temperatura.settemperatura (2, temperatura.gettemperatura(0)+10); będą równoważne. PP-9(24 z 85)

Przetwarzanie obiektów Specyfikacje opcjonalne w deklaracjach własności Dyrektywy default, nodefault i stored, zwane specyfikatorami pamięciowymi, podczas wykonywania programów generują pewne informacje dla własności określonych w sekcji published, które są (lub nie) zapisywane w pliku formatki. Nie są one dozwolone dla własności tablicowych (dla tych własności dyrektywa default ma inne znaczenie). Dyrektywy default i nodefault są dozwolone tylko dla własności typów porządkowych i małych zbiorów (typów zbiorowych, których typ bazowy ma liczby porządkowe od 0 do 31). Dyrektywa default postaci default stała określa domyślną wartość własności, przy czym typ stałej musi być taki sam, jak typ własności. Brak dyrektywy default lub podanie dyrektywy nodefault oznacza brak domyślnej wartości własności. PP-9(25 z 85)

Przetwarzanie obiektów Specyfikacje opcjonalne w deklaracjach własności Dyrektywa stored służy do sprawdzenia, czy wartość własności została zapisana w pliku podczas zapisywania stanu komponentu. Ma ona postać Brak tej dyrektywy oznacza domyślne przyjęcie stored True. Nazwa pola powinna określać pole typu Boolean, a nazwa metody metodę-funkcję o wartości Boolean. Jeśli wartością podanego pola lub metody-funkcji jest True lub podano stored True, to bieżąca wartość własności jest porównywana z wartością określoną dyrektywą default. Gdy wartość ta jest różna od wartości podanej tą dyrektywą lub dla własności nie podano dyrektywy default, to bieżąca wartość własności jest zapisywana do pliku. PP-9(26 z 85)

Przetwarzanie obiektów Pokrywanie własności Własności zadeklarowane w pewnym typie klasowym mogą być pokrywane w jego typach potomnych. Pokrycie może zmienić: P dostępność własności (np. przesunięcie z sekcji protected do sekcji published), P rodzaj dostępu do wartości (np. własności przeznaczonej tylko do odczytu można w typie potomnym nadać możliwość zapisu), P specyfikatory pamięciowe. PP-9(27 z 85)

Przetwarzanie obiektów Pokrywanie własności Przykład type TAncestor = class... inne deklaracje protected property Size : Integer read FSize; property Text : string read GetText write SetText; property Color : TColor read FColor write SetColor stored False;... inne deklaracje end; TDerived = class (TAncestor)... inne deklaracje zmiana zakresu dostępności dla własności Text i Color protected property Size write SetSize; published property Text; property Color stored False default clblue;... inne deklaracje end; dodanie możliwości zapisu wartości własności Size wartość własności Color będzie zapisywana w pliku formatki, jeśli jej wartością nie będzie stała clblue PP-9(28 z 85)

Przetwarzanie obiektów Własności klasowe Własności klasowe są deklarowane za pomocą słów class property Nie mogą mieć specyfikatorów stored i default oraz nie mogą być zamieszczane w sekcji published. Dostęp do wartości własności klasowych, które są zapisywane w polach klasowych (zadeklarowanych słowami class var) może być bezpośredni i pośredni, ale w drugim przypadku tylko za pomocą statycznych metod klasowych. PP-9(29 z 85)

Łącza programowe OLE, COM, ActiveX OLE (skr. ang. Object Linking and Embedding) - łączenie i wstawianie (osadzanie) obiektów; technologia opracowana przez firmę Microsoft, oznaczająca proces polegający na możliwości wstawiania do programu okienkowego, zwanego klientem lub sterownikiem, obiektu (tekstu, rysunku, arkusza kalkulacyjnego lub innego rodzaju informacji), który został utworzony przez inny program okienkowy, zwany serwerem. PP-9(30 z 85)

Łącza programowe OLE, COM, ActiveX Można wyróżnić dwa różne procesy: P jednorazowe dołączenie obiektu z innego programu, co nazywamy wstawieniem (osadzeniem) obiektu, Pdołączenie obiektu z innego programu z automatycznym uaktualnianiem, co nazywamy połączeniem obiektu. PP-9(31 z 85)

Łącza programowe OLE, COM, ActiveX OLE Automation (automatyzacja OLE) - możliwość programowego sterowania obiektami innego programu oraz protokół, poprzez który dany program może mieć dostęp do obiektu znajdującego się w innym programie lub bibliotece DLL. Obiekt automatyzacji OLE to obiekt programu-serwera, którym można manipulować z programu-klienta. Wersja 2.0 technologii OLE stała się podstawą do opracowania standardu COM (skr. ang. Component Object Model model obiektów składowych). PP-9(32 z 85)

Łącza programowe OLE, COM, ActiveX Standard COM jest standardem binarnym (nie jest oparty na kodzie źródłowym żadnego programu, czyli na żadnym języku programowania), co pozwala na komunikowanie się obiektów utworzonych w różnych programach, które są uruchomione w różnych przestrzeniach adresowych. Obiekty standardu COM są rozróżnialne na poziomie systemu operacyjnego poprzez unikatowe identyfikatory klasowe (ang. class identifiers, w skrócie CLSID), za pomocą których jest możliwy dostęp do nich (dokładniej: do pewnych ich części, zwanych łączami) i które służą także do tworzenia takich obiektów. PP-9(33 z 85)

Łącza programowe OLE, COM, ActiveX OCX - akronim angielskiej nazwy OLE control (element sterujący OLE), którą w późniejszym czasie zmieniono (głównie dla celów marketingowych) na ActiveX. Technologia ActiveX to rozszerzony na poziomie systemu operacyjnego standard COM, która zawiera dodatkowe zasady i własne biblioteki do tworzenia, zarządzania i operowania na obiektach COM. Komponenty ActiveX są niczym innym, jak obiektami standardu COM przeznaczonymi do wstawiania w innych programach środowiska Windows. PP-9(34 z 85)

Łącza programowe OLE, COM, ActiveX Typy klasowe zdefiniowane w bibliotece VCL i różne inne środki pakietu Delphi umożliwiają łatwe tworzenie programów z obiektami typu COM, OLE i ActiveX. Podstawowymi elementami programów COM, OLE i ActiveX są: P łącza programowe, stanowiące zestaw prototypów metod o określonych zastosowaniach, Pobiekty COM, które są instancjami klas, czyli obiektami powstałymi podczas wykonywania programu na podstawie definicji klas, implementującymi metody łącz programowych (klasy takie nazywa się koklasami ang. CoClasses), P fabryki klas, będące obiektami, które mogą tworzyć obiekty COM z określonych koklas, P biblioteki typów, które są zbiorami z informacjami o nazwach symbolicznych (typach, metodach i własnościach) wykorzystywanych w serwerach COM i Acive X, przy czym przez serwer należy tu rozumieć zbiór.exe,.dll lub.ocx, który zawiera kod dla obiektów COM i (lub) ActiveX. PP-9(35 z 85)

Łącza programowe OLE, COM, ActiveX Łącza programowe są grupami semantycznie powiązanych prototypów metod, których deklaracje określają tylko liczbę i typy parametrów, a w przypadku metod-funkcji także typ wartości funkcji. Z zestawu metod łącza powinno wynikać jego zastosowanie. Łącza nie określają jednak, w jaki sposób ich metody mają być implementowane, gdyż nie zawierają ich definicji. Aby metody łącz programowych były dostępne, należy zdefiniować klasy implementujące te łącza oraz utworzyć odpowiednie obiekty (zmienne typu klasowego). Łącza programowe mają unikatowe identyfikatory (globalne w systemie). Identyfikator taki jest 16-bajtową (128-bitową) wartością binarną i podczas programowania w środowisku Delphi może być przydzielony automatycznie. Tworzenie łącz programowych (poprzez komponenty ActiveX) w Delphi jest w znacznym stopniu zautomatyzowane. PP-9(36 z 85)

Dodatkowe info o modułach Części inicjująca i finalizująca Części inicjująca i finalizująca są opcjonalnymi częściami modułu. Część inicjującą rozpoczyna słowo kluczowe initialization, po którym występuje ciąg instrukcji. Część finalizująca może wystąpić tylko wówczas, gdy uprzednio określono część inicjującą. Rozpoczyna się ona słowem kluczowym finalization, po którym występuje ciąg instrukcji. PP-9(37 z 85)

Dodatkowe info o modułach Części inicjująca i finalizująca Końcowa część definicji modułu może więc mieć jedną z trzech następujących postaci: przy braku części inicjującej i finalizującej end. z częścią inicjującą (przy braku części finalizującej) initialization ciąg-instrukcji end. z częściami inicjującą i finalizującą initialization ciąg-instrukcji finalization ciąg-instrukcji end. PP-9(38 z 85)

Dodatkowe info o modułach Części inicjująca i finalizująca W części inicjującej umieszcza się zwykle instrukcje inicjujące dane (przypisujące im wartości) wykorzystywane przez moduł, a także przydzielające zasoby (pamięć, zbiory dyskowe itp.). Użycie przez program (inny moduł, bibliotekę łączoną dynamicznie) modułu z częścią inicjującą, tj. zadeklarowanie takiego modułu, powoduje wykonanie umieszczonych w tej części instrukcji przed jakimikolwiek innymi instrukcjami. Część finalizującą stosuje się głównie do zwolnienia zasobów przydzielonych w części inicjującej (jest to ważne w przypadku przerwania wykonywania programu wskutek wystąpienia błędu). PP-9(39 z 85)

Dodatkowe info o modułach Moduły wzajemnie zależne Są to moduły, które wykorzystują wzajemnie elementy w nich zdefiniowane. Postacie modułów wzajemnie zależnych są następujące: unit modul1; interface... implementation uses modul2;... end. unit modul2; interface... implementation uses modul1;... end. PP-9(40 z 85)

Biblioteki łączone dynamicznie Biblioteki łączone dynamicznie (w skrócie: biblioteki DLL od ang. dynamic-link libraries) służą do wspólnego używania kodów programowych i zasobów (danych definiujących wizualne części programów uruchamianych w środowisku Windows) przez różne programy i inne biblioteki DLL. Język Delphi umożliwia zarówno korzystanie z istniejących bibliotek DLL, jak i zaprogramowanie przez użytkownika własnych bibliotek tego typu. PP-9(41 z 85)

Biblioteki łączone dynamicznie Biblioteka łączona dynamicznie jest wykonywalną jednostką programową zawierającą kod programowy lub zasoby. W postaci skompilowanej jest pamiętana w zbiorze dyskowym o rozszerzeniu nazwy DLL. Podobieństwo bibliotek DLL do modułów: obie struktury programowe zawierają procedury i funkcje wykorzystywane przez programy, moduły i inne biblioteki DLL PP-9(42 z 85)

Biblioteki łączone dynamicznie Różnice pomiędzy bibliotekami DLL i modułami: P sposób dołączania do jednostek programowych (programów, modułów i innych bibliotek DLL), P moduły umożliwiają nie tylko wykorzystanie w programie procedur i funkcji, ale także literałów, typów i zmiennych w nich zdefiniowanych (w części opisowej), a z bibliotek DLL mogą być eksportowane tylko procedury i funkcje. PP-9(43 z 85)

Biblioteki łączone dynamicznie Dostęp do procedur i funkcji W celu użycia w programie (module, bieżącej bibliotece łączonej dynamicznie) procedury lub funkcji zdefiniowanej w danej bibliotece DLL należy w części opisowej programu (modułu, bieżącej biblioteki DLL) zadeklarować daną procedurę lub funkcję z dyrektywą external. Dyrektywa external określa odpowiednią bibliotekę DLL i wiąże deklarację z procedurą lub funkcją, która jest w niej zdefiniowana. PP-9(44 z 85)

Biblioteki łączone dynamicznie Przykład Dostęp do procedur i funkcji function okienko_komunikatu (identyfikator : Integer; komunikat, nagłówek : PChar; znaczniki : Integer) : Integer; stdcall; external user32.dll name MessageBoxA ; Dyrektywa języka stdcall określa konwencję wywołania funkcji. PP-9(45 z 85)

Biblioteki łączone dynamicznie Dostęp do procedur i funkcji Dla bibliotek DLL napisanych w języku Delphi, które będą wywoływane tylko w jednostkach programowych (programach, modułach i innych bibliotekach DLL) napisanych także w tym języku, określanie konwencji wywołania nie jest konieczne (domyślną konwencję określa dyrektywa register). W przypadku korzystania z bibliotek DLL napisanych w innych językach lub w bibliotekach pisanych w języku Delphi, ale przeznaczonych do wykorzystania w innych językach programowania, należy w deklaracjach funkcji i procedur podawać dyrektywę stdcall. PP-9(46 z 85)

Biblioteki łączone dynamicznie P nazwę, P nową (inną) nazwę, P liczbę porządkową. Dostęp do procedur i funkcji Program (moduł, bieżąca biblioteka DLL) napisany w języku Delphi może pobrać procedurę lub funkcję z danej biblioteki DLL przez: W każdym z tych sposobów postać dyrektywy external jest inna. PP-9(47 z 85)

Biblioteki łączone dynamicznie Dostęp do procedur i funkcji Import poprzez nazwę oznacza, że w tablicy nazw odpowiedniej biblioteki DLL będzie poszukiwany identyfikator danej procedury lub funkcji (po przekształceniu wszystkich małych liter na wielkie). Dyrektywa external ma w tym przypadku postać external nazwa-biblioteki; gdzie nazwa biblioteki w ogólności oznacza stałe wyrażenie łańcuchowe. Uwaga: Różnice pomiędzy starszymi wersjami systemu Windows: Windows 98, Me i XP a NT i 2000. PP-9(48 z 85)

Biblioteki łączone dynamicznie Przykłady Dostęp do procedur i funkcji 1) procedure proc_a; external PROCDLL.DLL ; Jeśli wcześniej zdefiniujemy stałą łańcuchową biblioteka_1 następująco: const biblioteka_1 = PROCDLL.DLL ; to podaną deklarację procedury proc_a można zastąpić deklaracją procedure proc_a; external biblioteka_1; 2) function NWP (const a, b : Longint) : Longint; external NUMLIB.DLL ; PP-9(49 z 85)

Biblioteki łączone dynamicznie Dostęp do procedur i funkcji Jeśli nazwa procedury lub funkcji w programie (module, bieżącej bibliotece DLL) ma być inna niż nazwa, za pomocą której eksportuje się ją z danej biblioteki, to należy zastosować importowanie przez nową (inną) nazwę. Dyrektywa external ma w tym przypadku postać external nazwa-biblioteki name nazwa-importowa; PP-9(50 z 85)

Biblioteki łączone dynamicznie Przykład Dostęp do procedur i funkcji function podzielnik (const a, b : Longint) : Longint; external NUMLIB.DLL name NWP ; PP-9(51 z 85)

Biblioteki łączone dynamicznie Dostęp do procedur i funkcji Import przez liczbę porządkową jest najbardziej efektywny, gdyż w tym przypadku odpowiedni identyfikator nie jest poszukiwany w tablicy nazw biblioteki. Liczba porządkowa procedury lub funkcji jest w bibliotece DLL ustalona za pomocą klauzuli exports (będzie dalej). Dyrektywa external odwołująca się do tej liczby ma postać external nazwa-biblioteki index liczba-porządkowa; PP-9(52 z 85)

Biblioteki łączone dynamicznie Przykład Dostęp do procedur i funkcji procedure proc_b; external PROCDLL.DLL index 15; Jeśli wcześniej określono następujące stałe: const biblioteka_1 = PROCDLL.DLL ; liczba_porz = 15; to podaną deklarację można zastąpić deklaracją procedure proc_b; external biblioteka_1 index liczba_porz; PP-9(53 z 85)

Biblioteki łączone dynamicznie Moduły importowe Procedury i funkcje mogą być pobierane z bibliotek DLL do programów (modułów, innych bibliotek DLL) w sposób bezpośredni (opisany bliżej) lub w sposób pośredni z modułów, które zawierają odpowiednie deklaracje. Moduły takie nazywamy modułami importowymi. Zalety stosowania modułów importowych: możliwośćumieszczaniawi chczęściachopisowychdefinicji i deklaracji stałych, typów i zmiennych, które ułatwiają dostęp do procedur i funkcji (bezpośrednie odwołanie się w programie do stałych, typów i zmiennych zdefiniowanych w bibliotece DLL nie jest możliwe), pomodyfikacjij akiejśbibliotekiwystarczyzmienićt ylkoodpowiedni moduł, a nie wszystkie programy (inne moduły, biblioteki DLL), które PP-9(54 z 85) korzystają z danej biblioteki.

Przykład Biblioteki łączone dynamicznie Moduły importowe unit cplcproc; interface type complex = record re, im : Extended end; function addcplx (const a, b : complex) : complex; function subcplx (const a, b : complex) : complex; function multcplx (const a, b : complex) : complex; function divcplx (const a, b : complex) : complex; implementation function addcplx; external CPLXPROC.DLL index 1; function subcplx; external CPLXPROC.DLL index 2; function multcplx; external CPLXPROC.DLL index 3; function divcplx; external CPLXPROC.DLL index 4; end. PP-9(55 z 85)

Biblioteki łączone dynamicznie Importowanie statyczne i dynamiczne Zastosowanie w programie (module, innej bibliotece DLL) dyrektywy języka external z nazwą danej biblioteki powoduje ustalenie biblioteki, z której będą pobierane procedury lub funkcje w sposób jawny. Pobieranie takie, zwane importowaniem statycznym, dotyczy zawsze tej samej procedury lub funkcji w tej samej bibliotece. Język Delphi umożliwia także ustalenie biblioteki i pobieranej z niej procedury lub funkcji dopiero podczas wykonywania programu. Ten sposób określania biblioteki i procedury lub funkcji nazywa się importowaniem dynamicznym. PP-9(56 z 85)

Biblioteki łączone dynamicznie Importowanie statyczne i dynamiczne Do przeprowadzenia importowania dynamicznego służą trzy funkcje standardowe: P LoadLibrary, P GetProcAddress, P FreeLibrary, które są zdefiniowane w module Winapi.Windows. PP-9(57 z 85)

Biblioteki łączone dynamicznie Importowanie statyczne i dynamiczne Funkcja LoadLibrary służy do wczytania biblioteki DLL do pamięci. Jej wywołanie ma postać LoadLibrary (nazwa-zbioru-bibliotecznego) Argument (typu PAnsiChar) wskazuje na łańcuch, który zawiera nazwę zbioru dyskowego z wczytywaną biblioteką. Gdy wczytanie biblioteki zakończy się pomyślnie, to wartością funkcji jest jej identyfikator w pamięci. Wartość funkcji równa 0 oznacza błąd podczas wczytywania biblioteki. Każde wywołanie funkcji LoadLibrary dla danej biblioteki zwiększa wewnętrzny licznik odwołań do niej o jeden. PP-9(58 z 85)

Biblioteki łączone dynamicznie Importowanie statyczne i dynamiczne Do zwolnienia pamięci zajętej przez bibliotekę służy funkcja FreeLibrary, której wywołanie ma postać FreeLibrary (identyfikator) Identyfikator oznacza argument będący wartością funkcji LoadLibrary, która wczytała daną bibliotekę do pamięci. Wartość funkcji jest o tyle nieistotna, że zwykle funkcję FreeLibrary wywołuje się jak procedurę. Wywołanie funkcji FreeLibrary powoduje zmniejszenie wewnętrznego licznika odwołań do danej biblioteki o jeden i jeśli licznik ten osiągnie wartość zero zwolnienie pamięci zajętej przez bibliotekę. PP-9(59 z 85)

Biblioteki łączone dynamicznie Importowanie statyczne i dynamiczne Dostęp (dynamiczny) do funkcji i procedur biblioteki DLL, która została wczytana do pamięci, jest możliwy poprzez adres, do którego otrzymania służy funkcja GetProcAddress. Jej wywołanie jest następujące: GetProcAddress (identyfikator, nazwa-funkcji-lub-procedury) gdzie identyfikator jest wartością funkcji LoadLibrary, a drugi argument (typu identycznego z PAnsiChar) wskazuje na łańcuch, który zawiera nazwę żądanej funkcji lub procedury lub też podaje jej liczbę porządkową. W drugim przypadku bardziej znaczące słowo musi być zerem, a słowo mniej znaczące podawać odpowiednią liczbę. Wartością funkcji GetProcAddress jest adres żądanej funkcji lub procedury, lub wartość nil, gdy funkcji lub procedury nie odnaleziono. PP-9(60 z 85)

Biblioteki łączone dynamicznie Importowanie statyczne i dynamiczne Przykład program programdll; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, Winapi.Windows;... type complex = record re, im : Extended end; var ident_1, ident_2 : HMODULE;... addcplx min deklaracja zmiennych do przechowywania identyfikatorów bibliotek : function (const a, b : complex) : complex; : function (const a, b : Extended) : Extended; deklaracja zmiennych proceduralnych reprezentujących w programie funkcje z biblioteki PP-9(61 z 85)

Biblioteki łączone dynamicznie Importowanie statyczne i dynamiczne Przykład (cd.) begin ident_1:=loadlibrary( C:\DELPHI\BIBL\CPLXPROC.DLL ); ident_2:=loadlibrary( A:\MIN_MAX.DLL ); wczytanie bibliotek do pamięci if ident_1<>0 then @addcplx:=getprocaddress(ident_1, PAnsiChar(1)); import dynamiczny przez liczbę porządkową PP-9(62 z 85)

Biblioteki łączone dynamicznie Przykład (cd.) Importowanie statyczne i dynamiczne if ident_2<>0 then @min:=getprocaddress(ident_2, MIN ); if @addcplx<>nil then begin... end; if @min<>nil then begin... end; import dynamiczny przez nazwę możliwość wywołania funkcji addcplx możliwość wywołania funkcji min PP-9(63 z 85)

Biblioteki łączone dynamicznie Przykład (cd.) Importowanie statyczne i dynamiczne if (@addcplx<>nil) and (@min<>nil) then begin... end; możliwość wywołania obu funkcji FreeLibrary (ident_1); FreeLibrary (ident_2);... end. usunięcie bibliotek z pamięci PP-9(64 z 85)

Biblioteki łączone dynamicznie Importowanie odwleczone Wczytanie biblioteki do pamięci można też odwlec (o ile nie korzystają z niej inne programy) do chwili pierwszego wywołania z niej funkcji lub procedury. Do wykonania tego procesu jest konieczne wyspecyfikowanie w dyrektywie external po nazwie biblioteki dodatkowej dyrektywy deleyed. Przykład function zmiana_x (const x : Byte) : Integer; external BiblZmian.dll delayed; Biblioteka BiblZmian zostanie wczytana do pamięci z chwilą pierwszego wywołania funkcji zmiana_x (pod warunkiem, że nie korzystają z niej inne programy i że nie są zniej pobierane inne funkcje i procedury). PP-9(64 z 85)

Biblioteki łączone dynamicznie Tworzenie bibliotek DLL Struktura biblioteki DLL jest następująca: library nazwa-biblioteki; deklaracje-modułów część-opisowa begin ciąg-instrukcji end. Sposób przekazywnia procedur i funkcji eksportowanych z biblioteki do programów lub modułów jest określony w części opisowej dodatkowymi klauzulami exports. Część wykonawcza bloku spełnia rolę części inicjującej biblioteki DLL. PP-9(66 z 85)

Biblioteki łączone dynamicznie Tworzenie bibliotek DLL W części opisowej biblioteki występują definicje funkcji i procedur eksportowalnych oraz (po nich) klauzule exports: exports lista-eksportowa; Elementy listy eksportowej oddziela się przecinkami, a każdy z nich może mieć jedną z następujących postaci: identyfikator identyfikator index liczba-porządkowa identyfikator index liczba-porządkowa name nazwa identyfikator name nazwa Dodatkowo na końcu każdego elementu listy eksportowej może wystąpić słowo (dyrektywa języka) resident. PP-9(67 z 85)

Biblioteki łączone dynamicznie Tworzenie bibliotek DLL Identyfikator występujący w każdym elemencie listy klauzuli exports jest nazwą odpowiedniej funkcji lub procedury eksportowej. Jeśli w elemencie listy klauzuli exports występuje dyrektywa języka index, oznacza to, że eksport funkcji lub procedury może odbyć się poprzez podaną liczbę porządkową. Liczba ta jest stałą całkowitą i może mieć wartość od 1 do 2 147 483 647. PP-9(68 z 85)

Biblioteki łączone dynamicznie Tworzenie bibliotek DLL Wystąpienie dyrektywy języka name umożliwia eksport funkcji lub procedury za pomocą wyspecyfikowanej nazwy, którą podaje się w postaci łańcucha. Brak dyrektywy name oznacza, że nazwą eksportową jest identyfikator danej funkcji lub procedury, którego wszystkie małe litery zostały zamienione na wielkie. Nazwa występująca w dyrektywie name elementu listy klauzuli exports jest tą samą nazwą, którą podaje się po słowie name w dyrektywie external w deklaracji importowanej funkcji lub procedury w programie, module lub innej bibliotece DLL. PP-9(69 z 85)

Biblioteki łączone dynamicznie Tworzenie bibliotek DLL W starszych wersjach języka Delphi po wczytaniu biblioteki DLL do pamięci dla elementów listy klauzuli exports, zawierających słowo resident, informacje o ich nazwach eksportowych były przechowywane w pamięci, co powodowało skrócenie czasu dostępu do funkcji i procedur importowanych przez nazwę. W obecnej wersji języka dyrektywa ta nie ma żadnego znaczenia. Podane dalej przykłady przedstawiają różne sposoby ustanawiania łącz pomiędzy biblioteką i programem w zależności od postaci klauzuli exports w bibliotece. PP-9(70 z 85)

Biblioteki łączone dynamicznie Tworzenie bibliotek DLL Przykład library min_max; function min (const a, b : Extended) : Extended; begin... end; function max (const a, b : Extended) : Extended; begin... end; exports min, max; begin end. PP-9(71 z 85)

Biblioteki łączone dynamicznie Tworzenie bibliotek DLL Przykład Deklaracje w programie: function min (const a, b : Extended) : Extended; external MIN_MAX.DLL ; function max (const a, b : Extended) : Extended; external MIN_MAX.DLL ; Z uwagi na standardowe przyjęcie nazw eksportowych w bibliotece, deklaracje funkcji min i max w programie mogą być także następujące: function min (const a, b : Extended) : Extended; external MIN_MAX.DLL name MIN ; function max (const a, b : Extended) : Extended; external MIN_MAX.DLL name 'MAX'; PP-9(72 z 85)

Biblioteki łączone dynamicznie Tworzenie bibliotek DLL Przykład Następujące deklaracje są błędne: function min (const a, b : Extended) : Extended; external MIN_MAX.DLL index 1; function max (const a, b : Extended) : Extended; external MIN_MAX.DLL index 2; Podczas wykonywania programu wystąpi warunek błędu EAccessViolation. Ponieważ importowanie funkcji odbywa się przez nazwy, w celu skrócenia czasu dostępu do nich można w klauzulę exports zapisać w postaci: exports min resident, max resident; PP-9(73 z 85)

Przykład Biblioteki łączone dynamicznie Tworzenie bibliotek DLL Dla klauzuli exports postaci exports min name MINAB resident, max name MAXAB resident; deklaracje funkcji w programie powinny być następujące: function min (const a, b : Extended) : Extended; external MIN_MAX.DLL name MINAB ; function max (const a, b : Extended) : Extended; external MIN_MAX.DLL name MAXAB ; PP-9(74 z 85)

Przykład Biblioteki łączone dynamicznie Tworzenie bibliotek DLL Możliwe jest też nadanie tym funkcjom w programie nowych nazw: function minimum (const a, b : Extended) : Extended; external MIN_MAX.DLL name MINAB ; function maximum (const a, b : Extended) : Extended; external MIN_MAX.DLL name MAXAB ; Nazwa funkcji (lub procedury) w bibliotece, nazwa eksportowa i nazwa funkcji (procedury) w programie (lub module) mogą być różne! PP-9(75 z 85)

Biblioteki łączone dynamicznie Tworzenie bibliotek DLL Przykład Jeżeli klauzula exports będzie miała postać exports min index 1, max index 2; to w programie poprawna będzie każda z poniższych deklaracji: function minimum (const a, b : Extended) : Extended; external MIN_MAX.DLL index 1; function maximum (const a, b : Extended) : Extended; external MIN_MAX.DLL index 2; function minimum (const a, b : Extended) : Extended; external MIN_MAX.DLL name MIN ; function maximum (const a, b : Extended) : Extended; external MIN_MAX.DLL name MAX ; PP-9(76 z 85)

Biblioteki łączone dynamicznie Tworzenie bibliotek DLL Przykład Jeżeli klauzula exports będzie miała postać exports min index 1, max index 2; to w programie poprawna będzie każda z poniższych deklaracji: function min (const a, b : Extended) : Extended; external MIN_MAX.DLL index 1; function max (const a, b : Extended) : Extended; external MIN_MAX.DLL index 2; function min (const a, b : Extended) : Extended; external MIN_MAX.DLL name MIN ; function max (const a, b : Extended) : Extended; external MIN_MAX.DLL name MAX ; PP-9(77 z 85)

Biblioteki łączone dynamicznie Biblioteki łączone dynamicznie mogą składać się z procedur i funkcji zdefiniowanych w kilku modułach. Zazwyczaj w takich przypadkach biblioteka składa się tylko z deklaracji modułów, klauzuli exports i części inicjującej. Jej struktura jest wówczas następująca: Tworzenie bibliotek DLL library nazwa-biblioteki; uses moduł-1, moduł-2,..., moduł-n; exports moduł-1.nazwa-11 index 1,... moduł-1.nazwa-1k index k,... moduł-n.nazwa-n1 index m nl+n1,... moduł-n.nazwa-nl index m; begin instrukcje-inicjujące end. PP-9(78 z 85)

Biblioteki łączone dynamicznie Tworzenie bibliotek DLL Instrukcje części inicjującej biblioteki są wykonywane tylko raz, podczas wczytywania biblioteki do pamięci. W chwili wprowadzania do programu kolejnego programu wykorzystującego daną bibliotekę jest zwiększany specjalny licznik jej wykorzystania. Biblioteka pozostaje w pamięci dopóty, dopóki licznik ten ma wartość większą od zera. Dla wartości licznika równej zeru jest wykonywana procedura wyjścia (zamknięcia) biblioteki, której adres jest pamiętany w predefiniowanej zmiennej ExitProc. PP-9(79 z 85)

Biblioteki łączone dynamicznie Część inicjująca zawiera zwykle: Tworzenie bibliotek DLL P instalację własnej procedury wyjścia, P instrukcje przypisujące wartości początkowe zmiennym globalnym biblioteki, P instrukcje rejestrujące klasy okienek (dotyczy bibliotek wykorzystywanych w programach okienkowych, które napisano przy użyciu biblioteki VCL, Pinstrukcję sygnalizującą wystąpienie błędu (najczęściej jest ona połączona ze sprawdzeniem wartości predefiniowanej zmiennej ExitCode, której wartość 0 oznacza bezbłędne zainicjowanie biblioteki, a wartość tej zmiennej różna od 0 powoduje usunięcie biblioteki z pamięci, a program, który ją wywołał, sygnalizuje błąd wczytywania biblioteki). PP-9(80 z 85)

Biblioteki łączone dynamicznie Tworzenie bibliotek DLL Przykład (zainstalowanie własnej procedury wyjścia) library Test; var SaveExit : Pointer; procedure LibExit; { własna procedura wyjścia biblioteki } begin... { instrukcje wykonywane przed usunięciem biblioteki z pamięci } ExitProc:=SaveExit end; begin... { inicjowanie biblioteki } SaveExit:=ExitProc; { zapamiętanie wskaźnika procedury wyjścia } ExitProc:=@LibExit { zainstalowanie procedury wyjścia LibExit } end. PP-9(81 z 85)

Biblioteki łączone dynamicznie Błędy wykonania w bibliotekach DLL W przypadku wystąpienia w bibliotece DLL, w której zadeklarowano moduł System.SysUtils, warunku błędu lub stanu wyjątkowego i nieobsłużenia go, warunek ten jest propagowany na zewnątrz biblioteki. Gdy biblioteka została wywołana z programu napisanego w języku Delphi, to warunek może być w nim obsłużony za pomocą instrukcji try...except. PP-9(82 z 85)

Biblioteki łączone dynamicznie Błędy wykonania w bibliotekach DLL Jeśli jednak daną bibliotekę wywoła program napisany w innym języku, to należy go w nim obsłużyć jako warunek błędu środowiska Windows o kodzie $0EEDFACE. Informacja o adresie błędu jest zawarta w pierwszym elemencie tablicy ExceptionInformation rekordu środowiska Windows o nazwie Exception_Record (informacje znajdują się w systemie pomocy). Drugi element tej tablicy zawiera odwołanie do obiektu reprezentującego błąd w języku Delphi. PP-9(83 z 85)

Biblioteki łączone dynamicznie Błędy wykonania w bibliotekach DLL Jeśli w bibliotece DLL nie zadeklarowano modułu System.SysUtils, to po wystąpieniu w niej błędu wykonywanie programu, który wywołał bibliotekę, zostanie przerwane (program zostanie usunięty z pamięci). Z tego powodu należy dokładnie przetestować taką bibliotekę, aby jakiekolwiek błędy wykonania nie mogły w niej wystąpić. PP-9(84 z 85)

... to już (dopiero) koniec na dzisiaj... PP-9(85 z 85)