MOJA PASJA - PROGRAMOWANIE
   Dzisiaj jest Niedziela, 23 kwietnia, 2017r. 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: 9842 (pokaż wszystkie)Skomentuj !   


Autor: AeienA81t08tData dodania: 2016-08-19
An additional issue is that video games usually are serious naturally with the primary focus on learning rather than leisure. Although, there is an enntitarnmeet aspect to keep your young ones engaged, every game is frequently designed to work towards a specific skill set or program, such as mathematics or scientific disciplines. Thanks for your posting.


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,



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