MOJA PASJA - PROGRAMOWANIE
   Dzisiaj jest Sobota, 4 lutego, 2012r. Ostatnia aktualzacja miała miejsce: 10 grudnia 2006r. Homepage

Programowanie: Artykuły * FAQ * Download * Komponenty * Książki WWW: Artykuły * Narzędzia * Kursy * Darmowe * FAQ * Skrypty * Ksiązki Off-Topic: Aforyzmy * Humor Inne: Forum * Wiki * Liczniki * Linki * Chat * Grafika * Video * Inne



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: jyJYvZaJsOFSKzULKiData dodania: 2009-03-22
qmtpptfo, cialis online, yvyatnpc, cialis barato, btumeuqe, viagra, cfjsentq, acheter cialis, lreaxjuu,


Autor: wbiSiNwMXvSpOwEZcLeData dodania: 2009-03-22
comment3, Cialis, 9213, Viagra, sonx,


Autor: Buy TramadolData dodania: 2009-03-22
Nise site., Phentermine , =-), Cheap viagra, aqco, Winston Cigarettes, :]]], Buy Ambien, 0290, Tramadol, 358,


Autor: MOkoLawktCRiYxSKData 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: MOkoLawktCRiYxSKData 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: LFfBQXLKcData dodania: 2009-03-22
rnbjcmac, cialis, xwkzmzrm, cheap cialis, oxrmfejl, viagra, sznynove, viagra, dmarlcqy,


Autor: Weight Loss PillsData dodania: 2009-03-22
I like your work!, Ionamine, 246769, Viagra, 99927, Ambien , 8[[, Buy Ultram, gaducs, Hoodia Gordonii, 01946,



Stronę przygotował: Kacper Cieśla (comboy). Wszelkie prawa zastrzeżone.
Reklama * Zgłoś błąd * Kontakt * Hosting * O stronie * Sponsoring
Czas generowania strony: 0.029s