Linux Dlopen System σε C

Linux Dlopen System Se C



Η συνάρτηση βιβλιοθήκης dlopen() είναι μια πολύ χρήσιμη συνάρτηση στη γλώσσα C. Η λειτουργία φορτώνει τη βιβλιοθήκη στη μνήμη αφού ανοίξει μια νέα. Γενικά το χρησιμοποιούμε για να φορτώνουμε τα σύμβολα της βιβλιοθήκης που είναι άγνωστα τη στιγμή της μεταγλώττισης. Η Dlopen() είναι μια συνάρτηση που χρησιμοποιείται στα προγράμματά μας. Η βιβλιοθήκη DL υλοποιεί την dlopen(), που ορίζεται στο Dlfcn.h. Για τη συνάρτηση dlopen απαιτούνται δύο παράμετροι: το όνομα του αρχείου της βιβλιοθήκης και η σημαία. Το όνομα του αρχείου είναι μια δυναμική βιβλιοθήκη και καθορίζει εάν οι εξαρτήσεις της βιβλιοθήκης υπολογίζονται αμέσως ή όχι. Η dlopen() επιστρέφει μια 'λαβή' η οποία θα πρέπει να θεωρείται ως αδιαφανής τιμή και άλλες λειτουργίες βιβλιοθήκης DL το χρησιμοποιούν. Εάν η προσπάθεια φόρτωσης είναι ανεπιτυχής, η dlopen() επιστρέφει NULL. Αλλά η dlopen() επιστρέφει την ίδια λαβή αρχείου εάν φορτώσει την ίδια βιβλιοθήκη πολλές φορές.

Κατά τη χρήση της συνάρτησης dlopen, ο μεταγλωττιστής δεν εξετάζει πιθανά σφάλματα, καθώς δεν γνωρίζει τους τύπους και τα πρωτότυπα που χρησιμοποιούμε. Η ανάπτυξη της λειτουργίας dlopen για τυπική φόρτωση δεν φαίνεται να προωθείται από αυτήν, εκτός από μερικές μικρές καταστάσεις. Παρεμπιπτόντως, είναι μια προσέγγιση για τη βελτίωση της ενδοσκόπησης. Όταν η κοινόχρηστη μονάδα χρησιμοποιείται αυτήν τη στιγμή από άλλο πρόγραμμα, η βελτιστοποίηση διάταξης μνήμης δεν ενδιαφέρεται ιδιαίτερα για τη φόρτωση υπό όρους. Το αποτύπωμα μνήμης δεν αυξάνεται όταν φορτώνεται μια βιβλιοθήκη που χρησιμοποιήθηκε στο παρελθόν. Η αποφυγή της παρακολούθησης του μεταγλωττιστή είναι επικίνδυνη και κάνει καλή εγγραφή σφαλμάτων. Επιπλέον, μας λείπει η πιθανή βελτιστοποίηση μεταγλωττιστή.

Παράδειγμα 1:

Τώρα, εξετάστε το ακόλουθο παράδειγμα για να δείτε τη λειτουργικότητα της συνάρτησης dlopen στη γλώσσα C. Στο πρώτο βήμα, φορτώνουμε μερικές βασικές βιβλιοθήκες C. Εδώ, φορτώνουμε τη νέα βιβλιοθήκη 'dlfcn.h' που χρησιμοποιείται για τον ορισμό των μακροεντολών κατά την κατασκευή του ορίσματος dlopen mode.







Στη συνέχεια, εισάγουμε μια άλλη βιβλιοθήκη μέσα στο πρόγραμμά μας 'gnu/lib-name.h'. Τα αρχεία κοινόχρηστης βιβλιοθήκης που περιλαμβάνονται στο GNU libc βρίσκονται από τα προγράμματα χρήστη σύμφωνα με τις μακροεντολές που ορίζει. Η Βιβλιοθήκη GNU C προσφέρει τις βασικές βιβλιοθήκες για τα λειτουργικά συστήματα GNU και GNU/Linux καθώς και ένα ευρύ φάσμα άλλων συστημάτων που βασίζονται σε Linux. Μετά από αυτό, έχουμε την εφαρμογή της κύριας μεθόδου. Μέσα σε αυτό, δηλώνουμε το αντικείμενο του δείκτη 'handle' με τη λέξη-κλειδί void. Δηλώνουμε μια συνάρτηση ημιτονοειδούς δείκτη που έχει τον τύπο δεδομένων διπλό. Υπάρχει μια άλλη δήλωση του αντικειμένου δείκτη 'σφάλμα' για τη διαχείριση σφαλμάτων.



Μετά από αυτό, καλούμε τη συνάρτηση dlopen μέσα στο αντικείμενο 'λαβή'. Το dlopen παίρνει δύο ορίσματα: LIBM_SO και 'RTLD_LAZY'. Εδώ, 'LIBM_SO' είναι το όνομα του αρχείου βιβλιοθήκης που παρέχει μαθηματικές συναρτήσεις όπως τριγωνομετρικές συναρτήσεις. Αυτή η κοινόχρηστη βιβλιοθήκη απαιτείται καθώς χρησιμοποιούμε τη συνάρτηση sine. Το 'RTLD_LAZY' είναι ένα άλλο όρισμα που καλεί τη συνάρτηση dlopen. Όταν ένα δεδομένο σύμβολο αναφέρεται για πρώτη φορά, οι μετεγκαταστάσεις πρέπει να πραγματοποιούνται σε χρόνο που καθορίζεται από την υλοποίηση.



Δεδομένου ότι μια διεργασία μπορεί να μην αναφέρεται σε κάθε σύμβολο σε ένα αρχείο εκτελέσιμου αντικειμένου, ο καθορισμός του RTLD LAZY θα πρέπει να βελτιώσει την απόδοση σε υλοποιήσεις που επιτρέπουν τη δέσμευση δυναμικών συμβόλων. Στη συνέχεια, έχουμε μια συνθήκη if-else για τον χειρισμό σφαλμάτων όταν το αντικείμενο χειρισμού αποτυγχάνει να εκτελέσει τη λειτουργία dlopen. Καλούμε το dlerror για να σβήσει το σφάλμα.





Η συνάρτηση dlerror() παρέχει μια συμβολοσειρά με μηδενικό τερματισμό που είναι αναγνώσιμη από τον άνθρωπο και καθορίζει την αναφορά του πρόσφατου σφάλματος που προκαλείται από μια κλήση σε μία από τις κλήσεις dlopen API από την τελευταία κλήση dlerror. Στη συνέχεια, ρίχνουμε τη συνάρτηση ως εξής: “(*void**)(&sine)= dlsym(handle, sin)”. Καθώς αυτό είναι περίεργο, το casting συμμορφώνεται με το ISO C που αποφεύγει τις προειδοποιήσεις από τον μεταγλωττιστή. Χρησιμοποιούμε τη συνάρτηση dlsym που παίρνει τη διαδρομή ενός συμβόλου που καθορίζεται μέσα σε μια λειτουργική μονάδα δυναμικής σύνδεσης η οποία είναι προσβάσιμη μέσω μιας συνάρτησης dlopen().

Επίσης, εκτελούμε ξανά τη λειτουργία if-else για το τυπικό σφάλμα που δημιουργείται όταν η dlerror() δεν είναι NULL. Στη συνέχεια, έχουμε μια δήλωση printf όπου καθορίζουμε την ημιτονοειδή τιμή που θα υπολογιστεί. Στο τελευταίο βήμα, κλείνουμε αυτό το κοινόχρηστο αντικείμενο καλώντας το dlclose για τη λαβή που επιστρέφει η dlopen().



#include
#include
#include
#include

ενθ
κύριος ( ενθ argc , απανθρακώνω ** argv )
{
κενός * λαβή ;
διπλό ( * δικο τους ) ( διπλό ) ;
απανθρακώνω * λάθος ;

λαβή = dlopen ( LIBM_SO , RTLD_LAZY ) ;
αν ( ! λαβή ) {
fprintf ( stderr , '%μικρό \n ' , dlerror ( ) ) ;
έξοδος ( EXIT_FAILURE ) ;
}
dlerror ( ) ;

* ( κενός ** ) ( & δικο τους ) = δλσυμ ( λαβή , 'χωρίς' ) ;

αν ( ( λάθος = dlerror ( ) ) != ΜΗΔΕΝΙΚΟ ) {
fprintf ( stderr , '%μικρό \n ' , λάθος ) ;
έξοδος ( EXIT_FAILURE ) ;
}

printf ( '%φά \n ' , ( * δικο τους ) ( 4.0 ) ) ;
dlclose ( λαβή ) ;
έξοδος ( EXIT_SUCCESS ) ;
}

Χρησιμοποιούμε την επιλογή -ldl με την εντολή C compilation αφού αυτή είναι η βιβλιοθήκη για τη συνδεδεμένη διεπαφή dlopen και απαιτείται. Όταν ολοκληρωθεί η εκτέλεση του αρχείου dlopen, εμφανίζει την ημιτονοειδή τιμή της τιμής που δόθηκε προηγουμένως.

Παράδειγμα 2:

Τώρα, παίρνουμε ένα άλλο παράδειγμα χρήσης της συνάρτησης dlopen. Φορτώνουμε το πρόγραμμά μας με όλες τις απαιτούμενες βιβλιοθήκες C για την υλοποίηση του κώδικα dlopen. Στη συνέχεια, ξεκινάμε το πρόγραμμά μας μέσα στην κύρια μέθοδο. Εδώ, ορίζουμε τη συμβολοσειρά με τη δήλωση της μεταβλητής “src”. Στη συνέχεια δηλώνουμε τις μεταβλητές δείκτη “strlen”, “handle” και “error”.

Στη συνέχεια, καλούμε τη μεταβλητή λαβής και αναπτύσσουμε τη συνάρτηση dlopen. Η συνάρτηση dlopen εισάγει την κοινόχρηστη βιβλιοθήκη 'libstr.so' για συναρτήσεις χειρισμού συμβολοσειρών και τη σημαία 'RTLD_LAZY' που έχει ήδη αποδειχθεί στο προηγούμενο παράδειγμα. Καλούμε τη συνάρτηση dlerror μέσα στη μεταβλητή «σφάλμα» για να καθαρίσουμε το σφάλμα που δημιουργείται από τη συνάρτηση dlopen. Το if-else χρησιμοποιείται για την εξέταση των σφαλμάτων.

Στη συνέχεια, λαμβάνουμε τη διεύθυνση της συνάρτησης strlen χρησιμοποιώντας τη συνάρτηση dlsym και επαληθεύουμε τα σφάλματα ενώ το κάνουμε αυτό. Μετά από αυτό, χρησιμοποιούμε τη συνάρτηση printf για να καλέσουμε τη συνάρτηση strnlen για να επιστρέψουμε το μήκος της δεδομένης συμβολοσειράς. Στο τέλος, κλείνουμε την κοινόχρηστη βιβλιοθήκη με τη συνάρτηση dlclose.

#include
#include
#include
#include
ενθ κύριος ( κενός )
{
απανθρακώνω * src = 'Γεια σου Linux' ;
ενθ ( * strlen ) ( συνθ απανθρακώνω * ) ;
κενός * λαβή ;
απανθρακώνω * λάθος ;


λαβή = dlopen ( './libstr.so' , RTLD_LAZY ) ;
λάθος = dlerror ( ) ;
αν ( ! λαβή || λάθος != ΜΗΔΕΝΙΚΟ ) { printf ( 'Η προσπάθεια φόρτωσης της βιβλιοθήκης απέτυχε! \n %μικρό \n ' , λάθος ) ;
ΕΠΙΣΤΡΟΦΗ - 1 ; }

strlen = δλσυμ ( λαβή , 'strlen' ) ;
λάθος = dlerror ( ) ;
αν ( ! strlen || λάθος == ΜΗΔΕΝΙΚΟ ) { printf ( '%μικρό \n ' , λάθος ) ; ΕΠΙΣΤΡΟΦΗ - 1 ; }

printf ( 'Το μήκος της χορδής είναι:%d \n ' , strlen ( src ) ) ;
dlclose ( λαβή ) ;
ΕΠΙΣΤΡΟΦΗ 0 ;
}

Χρησιμοποιούμε την παρακάτω εντολή για την εκτέλεση του συγκεκριμένου προγράμματος. Εδώ, η σημαία -lstr χρησιμοποιείται για τη συνάρτηση μήκους συμβολοσειράς και η ldl χρησιμοποιείται για το αρχείο βιβλιοθήκης dlopen. Το μεταγλωττισμένο πρόγραμμα δίνει το μήκος της συμβολοσειράς όπως φαίνεται στο κέλυφος:

συμπέρασμα

Οι πληροφορίες παρέχονται σχετικά με τη λειτουργία dlopen της γλώσσας C σε αυτό το άρθρο. Έχουμε μια σύντομη εισαγωγή της συνάρτησης dlopen. Στη συνέχεια, εφαρμόσαμε δύο παραδείγματα. Η συνάρτηση επιστρέφει ένα αναγνωριστικό που ορίζει την ανοιχτή βιβλιοθήκη. Στη συνέχεια, προσδιορίζονται οι διευθύνσεις των συναρτήσεων μέσα στην ανοιχτή βιβλιοθήκη χρησιμοποιώντας αυτό το αναγνωριστικό και τη συνάρτηση dlsym. Η διεύθυνση μιας συνάρτησης μέσα σε μια βιβλιοθήκη που έχει ήδη ανοίξει χρησιμοποιώντας το dlopen μπορεί να βρεθεί χρησιμοποιώντας τη συνάρτηση dlsym.