medigeek έγραψε:* Μπορεί κάποιος να φτιάξει ένα απλό c library και να δείξει πως καλείται και πώς γίνεται compile;
* Ποια η διαφορά των βιβλιοθηκών (libraries) static και linked; Μπορείτε να δείξετε ένα παράδειγμα χρήσης static και ένα linked library;
Στην απλή μορφή τους, δεν είναι κάτι το δύσκολο. Απλά δεν βάζεις main() σε κανένα αρχείο, κι αντί να βγάλεις εκτελέσιμο αρχείο στο τέλος, "μαζεύεις" τα *.o αρχεία μέσα σε ένα .a, με τη βοήθεια του: ar utility (man ar).
Αν δηλαδή έχεις φτιάξει μια συλλογή από reusable συναρτήσεις σε ένα αρχείο: libtest.c, τότε κάνεις:
- Κώδικας: Επιλογή όλων
gcc -c libtest.c
ar rvs libtest.a libtest.o
Αν έχεις πολλά .c αρχεία, κάνεις:
- Κώδικας: Επιλογή όλων
gcc -c *.c
ar rvs libtest.a *.o
Τα παραπάνω είναι για στατική βιβλιοθήκη .a που σημαίνει πως ο ενδιαφερόμενος την ενσωματώνει στο εκτελέσιμο αρχείο του, καλώντας την στο στάδιο του linker.
Μαζί με το .a αρχείο πρέπει να του δώσεις κι ένα .h αρχείο, το οποίο πρέπει κατ' ελάχιστο να περιέχει τα πρότυπα των συναρτήσεων που περιέχονται στα *.c αρχεία της βιβλιοθήκης, με το keyword: extern μπροστά τους.
Οπότε αυτός που θα πάρει το libtest.a και το libtest.h θα βάζει στον κώδικά του...
- Κώδικας: Επιλογή όλων
#include "libtest.h"
/* χρήση συναρτήσεων της βιβλιοθήκης libtest.a κατά το δοκούν */
και στο compilation θα γράφει:
- Κώδικας: Επιλογή όλων
gcc userprog.c libtest.a -o userprog
Με την προϋπόθεση πως τα αρχεία libtest.h και libtest.a βρίσκονται στον ίδιο φάκελο με το userprog.c
Αν θέλει μπορείς να βάλει το libtest.h στον φάκελο με τα υπόλοιπα include files του gcc, οπότε μέσα στα προγράμματά του, θα γράφει...
- Κώδικας: Επιλογή όλων
#include <libtest.h>
...
Κι αν βάλει και το libtest.a στο φάκελο με τις υπόλοιπες βιβλιοθήκες του gcc, τότε μπορεί να γράφει κατά το compilation...
- Κώδικας: Επιλογή όλων
gcc userprog.c -o userprog -ltest
Στον gcc για να μπορούν να κληθούν οι βιβλιοθήκες με το -l flag πρέπει να ξεκινάει με "lib" το όνομά τους και το υπόλοιπο του ονόματος (χωρίς το .a) πληκτρολογείται κολλητά μετά το -l.
Υπάρχουν και τα flags -I και -L που δηλώνουν σε ποιους φακέλους να ψάξει ο gcc για έξτρα .h και lib*.a αρχεία, αντίστοιχα (επιπρόσθετα δηλαδή των στάνταρ φακέλων του compiler).
Π.χ. αν έχεις μαζεμένα έξτρα αρχεία .h ας πούμε στον φάκελο: /usr/share/extrainclude/ και έξτρα αρχεία lib*.a ας πούμε στον φάκελο: /usr/share/extralibs/ τότε στη γραμμή εντολών του gcc μπορείς να δώσεις...
- Κώδικας: Επιλογή όλων
gcc userprog.c -o userprog -I/user/share/extrainclude -L/usr/share/extralibs -ltest
και μέσα στο userprog.c...
- Κώδικας: Επιλογή όλων
#include <libtest.h>
...
Όλα τα παραπάνω αφορούν τον gcc (και τον cc αν θυμάμαι καλά) αλλά ο κάθε compiler έχει δικές τους διαδικασίες και command flags για την δημιουργία και χρήση βιβλιοθηκών, συν ότι οι καταλήξεις και οι ονομασίες των αρχείων διαφέρουν από πλατφόρμα σε πλατφόρμα. Π.χ. στα Windows οι στατικές βιβλιοθήκες έχουν κατάληξη .lib (αντί για .a) ενώ οι δυναμικές έχουν κατάληξη .dll (αντί για .so που έχουν στο Unix/Linux... όπου s = shared).
Οι δυναμικές βιβλιοθήκες (ή αλλιώς shared) δεν γίνονται linked στο εκτελέσιμο αρχείο, αλλά πρέπει να προϋπάρχουν στο σύστημα ώστε να φορτωθούν δυναμικά όταν τις καλεί ένα πρόγραμμα, που χρησιμοποιεί συναρτήσεις τους.
Ορίστε και μερικά κατατοπιστικά links:
http://www.network-theory.co.uk/docs/gc ... ro_79.htmlhttp://tldp.org/HOWTO/Program-Library-H ... aries.htmlhttp://www.adp-gmbh.ch/cpp/gcc/create_lib.htmlΜπορείς να δοκιμάσεις να παίξεις με μια απλή και μικρή βιβλιοθήκη που έχω γράψει, που επεκτείνει τη λειτουργικότητα της στάνταρ βιβλιοθήκης για strings:
http://x-karagiannis.gr/prog/libs/Είναι σε pre-Alpha κατάσταση, αλλά μπορείς να τη χρησιμοποιήσεις ως απλό, ζωντανό παράδειγμα για να πειραματιστείς (ένα .h κι ένα .c αρχείο είναι όλα κι όλα).
ΥΓ. Δεν είναι απαραίτητο να φτιάξεις .a αρχείο, μπορείς να χρησιμοποιείς απευθείας τα .o αρχεία μια βιβλιοθήκης. Επίσης στο .h αρχείο μιας βιβλιοθήκης εκτός από πρότυπα συναρτήσεων μπορεί να βρεις και data structures ή/και καθολικές μεταβλητές της βιβλιοθήκης. Ανάλογα με το τι χρειάζεται να είναι public, και που προφανώς το καθορίζει ο δημιουργός της βιβλιοθήκης, βάζοντάς το στο .h που διανείμει.