|
Dynamiczne dołączanie bibliotek dll
Autor: Vnookality
Na grupie dyskusyjnej pl.comp.lang.c padło kiedyś pytanie: "... czy mogę jakoś korzystać z bibliotek dll bez tworzenia pliku *.lib i importowania go do projektu?". Rozwiązanie oczywiście jest i jest oczywiście lepsze od importowania *.lib'a. Po pierwsze taka biblioteka jest ładowana do pamięci wraz z głównym modułem programu. Jest to o tyle złe, że gdy mamy zbyt mało pamięci i ogromną ilość modułów *.dll do zaimportowania, to może jej w końcu nie wystarczyć, lub bardzo nieprzyjemnie spowalniać pracę programu i wraz z tym innych aplikacji. Zalet dynamicznego dołączania i zwalniania bibliotek dll to między innymi:
- lepsze zarządzanie pamięcią. Gdy biblioteka jest nam potrzebna, ładujemy ją, a gdy przestaje - zwalniamy ją po prostu z pamięci.
- możliwość umieszczania dll'i w dowolnym katalogu programu. Gdybyśmy użyli importowania lib'a biblioteka dll musiałaby znajdować się w głównym katalogu programu, co nie wszystkim może pasować.
- nie musimy tworzyć wspomnianych plików importowych. To bardzo przyspiesza tworzenie aplikacji i nie wymaga od nas używania innych dodatkowych programów takich jak implib.exe czy też impdef.exe.
Poniżej pokażę przykład takowej biblioteki. Jak je tworzyć? Trochę inaczej niż biblioteki z plikami importowymi. Tutaj musimy użyć Incremental linker'a. Inaczej naszej biblioteki nie będzie można załadować do pamięci. Oto przykładowy kod takiej biblioteki:
|
Unit1.cpp |
|
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport) void __stdcall RunThisModule();
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
return 1;
}
//---------------------------------------------------------------------------
void __stdcall RunThisModule()
{
ShowMessage("Hello!");
}
//---------------------------------------------------------------------------
| |
|
Powyższy przykład pokazuje Message'a z napisem "Hello". Jest to najprostsza biblioteka jaka przyszła mi do głowy. No, ale mniejsza z tym. Bibliotekę trzeba (to chyba jasne...) skompilować jako dll. Powiedzmy, że plik biblioteki nazywa się Tutorial.dll. Nazwa dll'a jest bardzo ważna! Sprawdź ją i najlepiej zapamiętaj lub zapisz.
Teraz czas na program, który wykorzysta naszą bibliotekę. Ten fragment jest najważniejszy. Od niego zależy, czy program po pierwsze załaduje bibliotekę i znajdzie naszą funkcję. Przyjrzyj się poniższemu przykładowi. Potem opiszę cały kod.
W pliku nagłówkowym (przed deklaracją klasy TForm):
|
Unit1.h |
|
typedef void __stdcall (*PROCRunThisModule)();
extern "C" void __stdcall RunThisModule();
|
|
W pliku źródłowym:
|
Unit1.cpp |
|
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HINSTANCE NaszDLL;
NaszDLL = LoadLibrary("Tutorial.dll");
if (NaszDLL == NULL)
{
Application->MessageBox("Nie można załadować Biblioteki dll!","Błąd",
MB_OK | MB_ICONHAND);
}
else
{
PROCRunThisModule _RunThisModule =
(PROCRunThisModule)GetProcAddress(NaszDLL, "RunThisModule");
if (_RunThisModule == NULL)
{
Application->MessageBox("Nie znalazłem zdefiniowanej funkcji!","Błąd",
MB_OK | MB_ICONHAND);
}
else
{
_RunThisModule();
}
}
}
|
|
A teraz opis powyższego kodu. Najpierw tworzymy uchwyt dla naszej biblioteki, czyli w tym przypadku HINSTANCE NaszDLL. Następnie ładujemy bibliotekę dll (LoadLibrary()). Należy zauważyć, że przy ładowaniu dll'a można wprowadzić dowolną ścieżkę dostępu do dll'a. I ważne! Najpierw program próbuje załadować plik o zdefiniowanej nazwie z katalogu głównego programu, a jeżeli jej nie ma, to próbuje znaleźć ją w głównym katalogu Windows'a. Można się o tym przekonać, kasując nasz plik Tutorial.dll z katalogu głównego programu, a kopiując go do katalogu Windows'a. Efekt jest ten sam. Dalej sprawdzamy, czy biblioteka została załadowana. Jeżeli wartość jest równa NULL, zostaje pokazane okno z komunikatem o niepowodzeniu. Jeżeli jest inaczej, program sprawdza czy podana funkcja znajduje się w dll'u. Tak jak wyżej, jeżeli wartość jest równa NULL, zostaje pokazany komunikat. Jeżeli nie byłoby funkcji warunkowej if, program zwróciłby błąd "External exception". Lepiej wygląda jednak błąd zdefiniowany przez nas ;) Jeżeli jednak funkcja występuje, program wykonuje ją.
Bibliotekę zwalniamy funkcją FreeLibrary("Tutorial.dll"), którą najlepiej umieszczać zaraz po funkcji wywoływanej z dll'a. Jeżeli jest to jednak funkcja wywołująca okno nie modalne, należy pamiętać, że program będzie próbował zwolnić bibliotekę z pamięci mimo iż jest ona używana! W takim wypadku najlepiej deklarację uchwytu naszej biblioteki wstawić tuż pod nazwami plików nagłówkowych, a funkcję FreeLibrary w zdarzeniu OnClose() formy.
To by było na tyle. Jeżeli masz jakieś kłopoty, zawsze możesz napisać na mój e-mail: vnookality@poczta.fm lub vnookality@go2.pl. No i... szybkiego kompilowania i zera error'ów :)
| Wasze opinie: |
| Średnia ocena: 6.09/10 (54 głosów) |
|
| Liczba komentarzy: 9841 (pokaż wszystkie) | Skomentuj !
|
| Autor: wbiSiNwMXvSpOwEZcLe | Data dodania: 2009-03-22 |
| comment3, Cialis, 9213, Viagra, sonx, |
| Autor: Buy Tramadol | Data dodania: 2009-03-22 |
| Nise site., Phentermine
, =-), Cheap viagra, aqco, Winston Cigarettes, :]]], Buy Ambien, 0290, Tramadol, 358, |
| Autor: MOkoLawktCRiYxSK | Data dodania: 2009-03-22 |
| Hi webmaster! Your site is cool, indeed! Please visit my homepage:, shortness, [url="http://kluuqkh.fcpages.com/ptidesund.html"]shortness[/url], http://kluuqkh.fcpages.com/ptidesund.html shortness, 9800, cheek, [url="http://pasgepa.envy.nu/gha.html"]cheek[/url], http://pasgepa.envy.nu/gha.html cheek, >:(, |
| Autor: MOkoLawktCRiYxSK | Data dodania: 2009-03-22 |
| Great work! It very impressive. Your web site is helpful. All the best!, legs, [url="http://qadiaiu.freewebsitehosting.com/amandnys.html"]legs[/url], http://qadiaiu.freewebsitehosting.com/amandnys.html legs, mkpur, diarrhea, [url="http://ciuatir.b-w-h.com/iredsio.html"]diarrhea[/url], http://ciuatir.b-w-h.com/iredsio.html diarrhea, fgtfs, |
| Autor: Weight Loss Pills | Data dodania: 2009-03-22 |
| I like your work!, Ionamine, 246769, Viagra, 99927, Ambien
, 8[[, Buy Ultram, gaducs, Hoodia Gordonii, 01946, |
|
|