Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Tworzenie bibliotek DLL w języku C i odwoływanie się do nich

Krzysztof Gustaw 24 Jun 2013 21:12 2856 11
  • #1
    Krzysztof Gustaw
    Level 23  
    Witam!
    Mam zamiar (wreszcie) stworzyć własną bibliotekę DLL. Piszę w klasycznym tzn. ANSI "C" a i "K&R C" nie jest mi obcy. Używam darmowego kompilatora Pelles C. Orientuję się z grubsza czym to się je ale korzystam głównie z książki (świetnej!) "Windows od kuchni" napisanej przez Pana Rolanda Wacławka. Jednak w tej książce Autor używa języka PASCAL w którym nie za bardzo się czuję... Proszę Was tylko o szkielet programu biblioteki oraz o instruktaż w jaki sposób odwoływać się do funkcyj zawartych w utworzonej przeze mnie bibliotece z poziomu "klasycznego" programu... Nie jestem biegły w języku angielskim... Powtarzam, TYLKO język "C"...
    Będę wdzięczny za sugestie...
    Pozdrówka
    K.G.
  • #2
    McMonster
    Level 32  
    Na tej playliście jest kilka odcinków na temat DLL i pluginów. Polecam też cały kanał jako taki.
  • Helpful post
    #3
    stanleysts
    Level 27  
    Poszukaj w Windows API, http://cpp0x.pl/kursy/Kurs-WinAPI-C++/Zaawansowane/DLL/198 to też może być przydatne.

    Z poziomu WinApi to wygląda mniej więcej tak, że na podstawie gotowych funkcji WinApi pobierasz adres (wskaźnik) szukanej funkcji i potem się tym wskaźnikiem posługujesz.
  • #4
    Krzysztof Gustaw
    Level 23  
    Witam!
    O dzięki Ci, stanleysts!
    Przeczytałem podany przez Ciebie link i udało mi się stworzyć DLL-kę. Miałem na początku problemy bo aplikacja ćwiczebna nie znajdowała ćwiczebnej funkcji w ćwiczebnej DLL-ce ale wyedytowałem sobie plik wynikowy dll i znalazłem, że dołożyło mi do nazwy "krzaczki". W związku z tym włączyłem w swoim Pelles C opcję kompilatora "undecorate exported __stdcall function" i poszło!
    Tematu jeszcze nie zamykam bo to jest wierzchołek góry lodowej.
    Pozdrowienia!
    K.G.
  • #5
    stanleysts
    Level 27  
    Zeby nie dorabiało krzaczków to chyba wystarczy zaopatrzyć się w dyrektywę "extern C" i obudować nią blok funkcji, bo wtedy kompilator chyba nie dokłada tych krzaków, bo i po co nie ma takiego czegoś jak przeładowanie.
  • #6
    Krzysztof Gustaw
    Level 23  
    Witam!
    Do stanleysts
    W pierwszej kolejności spróbowałem Twojego rozwiązania (chodzi o dyrektywę "extern C") ale nie zadziałała...
    Aha, być może moim błędem było to, że w dyrektywie "extern C", słowo C obudowałem znakami cudzysłowia...
    Muszę to sprawdzić...
    To tyle dla innych użytkowników przeglądających mój wątek...
  • #7
    stanleysts
    Level 27  
    Dobrze obudowałeś :D
    extern "C" {
    void foo(void);
    }
  • #8
    Krzysztof Gustaw
    Level 23  
    Witam ponownie!
    W swojej pracy korzystam z kompilatora Pelles C w którym czuję się najlepiej, a tenże nie jest kompilatorem C++ stąd te trudności w obudowywaniu dyrektywą extern "c" itd.
    Interesują mni JEDYNIE odpowiedzi w języku polskim.
    Mam teraz kolejne pytanie: w linku podanym mi przez Kolegę stanleysts znalazłem podstawy budowy DLL i bardzo mi to pomogło, ale (niestety) wykorzystywane są tutaj mechanizmy C++ którego Pelles C "nie rozumie", np konstruktor i destruktor (to akurat wiem, czym to się je ale mój ulubiony Pelles C - nie). W klasycznym języku C inicjowaniem parametrów, przydzielaniem pamięci, tworzeniem nowych klas okien (nie utożsamiać z klasą w sensie class cośtam a dotyczącym C++!) itp itd zajmuje się funkcja LibMain(). Po zakończeniu pracy z biblioteką, wypadałoby ją zamknąć funkcją FreeLibrary. Ale przy zakończeniu biblioteka powinna po sobie posprzątać, np zwolnić pamięć zaalokowaną w momencie inicjalizacji przez LibMain(). W takim przypadku musi być wywołana (być może niejawnie) jakaś funkcja a'la destruktor. W Pascalu jest to bezparametrowa funkcja wep() z indeksem 1 i jest wywołana niejawnie w momencie zamykania biblioteki.
    I w związku z tym pytanie:
    Czy, a jeśli tak, to jaka równoważna funkcja istnieje w języku C (a nie C++) ?
    Innymi słowy:

    (PASCAL) Pierwsze ładowanie biblioteki
    program główny biblioteki czyli

    begin
    ...
    end.

    Likwidacja biblioteki - niejawne wywołanie funkcji wep.

    (C)

    Pierwsze ładowanie
    LibMain()
    {
    ...
    }

    Likwidacja - niejawne wywołanie funkcji (???)
  • Helpful post
    #9
    stanleysts
    Level 27  
    A to nie jest tak, że masz funkcję libmain/dllmain i tam masz switcha w którym możesz sobie te zasoby zwolnić?
    Bo wyłołanie funkcji load library/FREE LIBRARY powoduje chyba wywolanie tej dllmain z odpowiednim parametrem attach/detach.
  • #10
    Krzysztof Gustaw
    Level 23  
    Witam!
    Sprawdziłem, faktycznie jest tak jak piszesz. Działa. Cóż sądziłem, że funkcja DllMain wywoływana jest tylko raz w trakcie ładowania biblioteki jako że jest to niejako program główny, a tu patrzcie państwo...
  • #11
    stanleysts
    Level 27  
    No jest wywoływana też w kilku innych momentach, zresztą się już o tym przekonałeś.
  • #12
    Krzysztof Gustaw
    Level 23  
    Tak, zorientowałem się ale póki co, w wątki nie wchodzę (te wyścigi, semafory, Problem Pięciu Filozofów...), za stary już jestem :)
    A swoją drogą, co do tych ATTACHów w switch sądziłem że to jest tak, że jakiś program np debugger próbuje wbijać się w już działający proces (bo gdyby to było nazwane np INITLIB, EXITLIB to bym się zorientował od razu), stąd moje poprzednie wątpliwości...
    Dziękuję i pozdrawiam!