dll5 QSN26ROADE3VE6ONPGQAT4SX7LOHQE4SWULRJUA



Strefa C++ Builder'a





















Jak utworzyć bibliotekę DLL (wprowadzenie)      Strona
5 z 7        Dalej



w oparciu o materiały ze stron The Bits




      
Krok 4: Dodanie formularza do biblioteki


      Formularz jest przygotowany do dodania go do biblioteki. Jak dotąd, zadeklarowaliśmy co ma on
robić i jak może służyć użytkownikowi, ale nasz formularz nie przynależy jeszcze do żadnego
projektu. Jest odizolowany, jak sierota czekająca na adopcję. Aby połączyć formularz z
biblioteką musimy zrobić dwie rzeczy.



      Najpierw trzeba powiadomić DLL-a o istnieniu formularza, tzn. jego klasy i skąd dziedziczy.
Następnie trzeba utworzyć egzemplarz formularza w czasie wykonywania, a po skończeniu pracy
z nim, zlikwidować go.



      Musisz sam wyedytować plik TUTORIAL.CPP. Builder nie zrobi tego za ciebie, gdyż projekt
twojej biblioteki DLL nie stosuje się do standardowych protokołów programów GUI. Zmień
treść pliku tak, żeby wyglądał jak poniżej:




//-----------------------------------------------------

#include <vcl.h>

#include <stdio.h>

#pragma hdrstop

#include "Add2Nos.h"

//-----------------------------------------------------

static short int siDLL_MAJOR_VERSION_NO = 1;

static short int siDLL_MINOR_VERSION_NO = 0;

//-------------------------------------------------

USEFORM("Add2Nos.cpp", frmAddNumbers);

//-------------------------------------------------

extern "C" __declspec(dllexport) void VerNo(short int*,
short int*);

extern "C" __declspec(dllexport) bool Add2(char*,
char*, long int*);

void GetVersionNumbers(short int*, short int*);

//--------------------------------------------------

int WINAPI DllEntryPoint(HINSTANCE hinst,
unsigned long reason, void*)

{

return 1;

}

//--------------------------------------------------

void VerNo(short int* iMAJOR, short int* iMINOR)

{

GetVersionNumbers(iMAJOR, iMINOR);

return;

}

//---------------------------------------------------


void GetVersionNumbers(short int* iMAJOR_VERSION,
short int* iMINOR_VERSION)

{

*iMAJOR_VERSION = siDLL_MAJOR_VERSION_NO;

*iMINOR_VERSION = siDLL_MINOR_VERSION_NO;

return;

}

//-------------------------------------------------

bool Add2(char* cText1, char* cText2, long int *Sum)

{

long int i, j;

char cString1[20], cString2[20];

bool bMyLocalResult;

TfrmAddNumbers *X = new TfrmAddNumbers(NULL);

X->Edit1->Text = (AnsiString)cText1;

X->Edit2->Text = (AnsiString)cText2;

X->ShowModal();

bMyLocalResult = X->bResult;

strcpy(cString1, X->Edit1->Text.c_str());

strcpy(cString2, X->Edit2->Text.c_str());

delete X;

if(!bMyLocalResult) return false;

sscanf(cString1, "%d", &i);

sscanf(cString2, "%d", &j);

*Sum = i + j;

return true;

}




      Na początku, dodajemy plik nagłówkowy Add2Nos.H, który definiuje formularz. Deklaracje
funkcji Add2 i VerNo są do siebie w pewnym sensie podobne. Jeśli funkcje mają być używane
na zewnątrz biblioteki, musimy wyeksportować ich nazwy. Potem musimy tylko zaprogramować
to, co funkcje mają zrobić. Ponieważ sami tworzymy formularz, musimy wpisać odpowiedni kod
w funkcji Add2. Pierwszą rzeczą jaką musimy zrobić, jest stworzenie egzemplarza naszego
formularza.



      I tu właśnie używamy następującej konstrukcji:





TfrmAddNumbers *X=new TfrmAddNumbers(NULL);




      Tworzymy obiekt X jako wskaźnik do formularza, obiekt ten będzie symbolizował nasz
formularz. W tym momencie egzemplarz już istnieje, a my możemy obiektowi X przypisywać
wszelkie właściwości, metody oraz zdarzenia, z których korzystamy przy projektowaniu
formularzy w IDE. Sam formularz już powstał, ale nie jest jeszcze widoczny na ekranie. Zanim go
jednak "uwidocznimy" zauważ, że biorę z funkcji wywołującej dwa stringi i używam ich do
zainicjalizowania zawartości pól edycyjnych Edit1, Edit2.
Spójrz na nazwę w powyższej konstrukcji i przypomnij sobie nazwę formularza (jego właściwość
Name w tabeli przy punkcie 2). Builder dodaje przedrostek "T" jako część konwencji
nazewniczej dla klas. Naszemu formularzowi nadaliśmy nazwę frmAddNumbers, więc Builder
stworzył klasę o nazwie TfrmAddNumbers. Po prostu miej na uwadze, że jeśli podasz nazwę
czegoś co nie istnieje, kompilator wyrzuci błąd.



      Być może zauważyłeś już pewną słabość jaka tu występuje: nie sprawdzamy poprawności
wpisywanych przez użytkownika danych do pól edycyjnych. No, ale przecież ten samouczek
dotyczy DLL-i, a takie sprawdzenie możesz wykonać bez mojej pomocy. Dopiero dzięki
wyrażeniu X->ShowModal() nasz formularz fizycznie pojawia się na ekranie. Będąc tzw. oknem
modalnym, wstrzymuje on pracę aplikacji aż do momentu jego zamknięcia. To znaczy, jeśli na
ekranie mamy formularz w trybie modalnym, to nie możemy przejść do innych formularzy bez
wcześniejszego zamknięcia tego modalnego. Formularze się pojawiają, użytkownik wpisuje tekst i
klika któryś z dwóch przycisków. Kiedy użytkownik zamyka formularz, wykonywane są
instrukcje następujące po X->ShowModal(). I tak, najpierw zapisałem wartość zmiennej bResult
w formularzu (pamiętasz?, zadeklarowaliśmy ją w sekcji public) i teraz przypisuję ją do naszej
nowej zmiennej typu bool w bibliotece (bMyLocalResult) Potem robimy kopie bieżących
zawartości pól edycyjnych.



      Następnie likwidujemy obiekt X. UWAGA!!! Jeżeli tworzysz obiekt w czasie wykonywania,
po zakończeniu operacji na nim, zawsze go usuń! Jeśli tego nie zrobisz, narażasz się na
trudną do wykrycia konsumpcję pamięci. Zanim wywołasz metodę ShowModal, możesz
robić z danym obiektem co tylko chcesz. Po tej metodzie - jest już za późno! Kiedy
zamkniesz formularz modalny, to pobierz wszystkie potrzebne ci informacje z obiektu
zanim go zlikwidujesz.



      Później, funkcja Add2 sprawdza wartość zmiennej typu bool którą zapisaliśmy przed
zlikwidowaniem formularza. Jeśli wartość jest równa 0, to wciśnięto Anuluj, i zwracamy ten stan.
Jeśli wartość jest 1, to znaczy że wciśnięto przycisk Oblicz. Zerknij do treści funkcji dla zdarzenia
OnClick przycisku Oblicz. Jest to jedyne miejsce, gdzie wartość ta jest ustawiana na 1 (true). W
końcu przekształcamy te dwa stringi wzięte z pól edycyjnych na binarne (sscanf) a ich sumę
zwracamy potem w parametrze SUM. Nadajemy również całej funkcji Add2 wartość true, żeby
w razie potrzeby program mógł wykonać jakieś specjalne działanie na parametrze SUM. Na tym
właściwie kończy się samo tworzenie biblioteki DLL. Już prawie po krzyku!



      Krok 5: Utworzenie biblioteki importowej (.lib)


      Musimy jeszcze zrobić parę rzeczy. Wybierz Project/Make w celu skompilowania i zlinkowania
wprowadzonego kodu. Nie powinieneś dostać żadnych błędów więc sprawdź swój kod i usuń
ewentualne literówki przed kompilacją. Kolejnym krokiem jest utworzenie spisu zawartości
biblioteki DLL, przy użyciu narzędzia zwanego implib. Taki spis (biblioteka importowa) będzie
używana w każdym programie korzystającym z DLL-a. Niestety C++Builder nie pokazuje implib
w menu Tools, zatem musisz przejść do okna DOS-u.



      Biblioteka importowa stanowi pomost pomiędzy programem a DLL-em. Ma decydujące
znaczenie przy określaniu zawartości biblioteki DLL. Bez niej, twój program nie byłby w stanie
używać żadnych funkcji DLL-a. Zatem do dzieła: kliknij Start/Programy/Tryb MS-DOS. Zmień
katalog na DLLTUTOR. C++Builder dostarczany jest z programem implib.exe, który powinien
znajdować się w katalogu Program Files/Borland/Builder/Bin. Podczas instalacji C++Builder
zadbał już o to, abyś mógł uruchamiać implib.exe z każdego innego katalogu - po prostu umieścił
w.w. ścieżkę w pliku autoexec.bat.



      Wpisz poniższą komendę:





implib tutorial.lib tutorial.dll



      Program implib przeczyta pozycje funkcji w DLL-u (stworzone przez Builder'a) i utworzy w
bieżącym katalogu bibliotekę importową o nazwie TUTORIAL.LIB i rozmiarze ok. 2Kb. Możesz
już używać biblioteki importowej oraz DLL-a w twoim programie. TUTORIAL.LIB posiada
nazwy funkcji eksportowanych. Skopiuj teraz TUTORIAL.LIB i TUTORIAL.DLL do drugiego z
utworzonych przez ciebie katalogów, a mianowicie do TESTPROG.



      Jak często musisz używać implib? To zależy od tego co zmieniasz w DLL-u. Jeżeli chcesz dodać
lub usunąć z biblioteki jakieś funkcje eksportowane, to na pewno po każdej takiej zmianie musisz
użyć implib. Reguła ta dotyczy jednak tylko funkcji eksportowanych, nie dotyczy to funkcji
wewnętrznych. Ostatnio utworzona biblioteka importowa stanowi dla twojego programu swego
rodzaju spis treści tego co zawiera DLL, pomijając fakt że mogłeś już usunąć stamtąd jakąś
funkcję. Mógłbyś być bardzo niemile zaskoczony, gdyby twój program odwołał się do DLL-a w
poszukiwaniu funkcji, która tam nie istnieje.



      Nie musisz powtórnie używać implib, jeśli tylko zmieniasz kod w definicji funkcji lub jej
parametry. Jak już mówiłem, biblioteka importowa jest takim indeksem tego co znajduje się w
DLL-u, a nie tego, jak jest to wykonywane.










Uwaga: Autorzy oraz The Bits, nie ponoszą odpowiedzialności za ewentualne
szkody wynikłe z postępowania według zasad tego samouczka.
(c)1998 Peter Hamilton-Scott, Dallen Masters, & Simon Rutley-Frayne.
1999 Allan Carlton & Will Green. 
Tłumaczenie:  Maciek Durman




1  2  3  4  5  6  7















Wyszukiwarka

Podobne podstrony:
dll5

więcej podobnych podstron