Linux Dlopen System in C

Linux Dlopen System In C



Kirjastofunktio dlopen() on erittäin hyödyllinen funktio C-kielessä. Toiminto lataa kirjaston muistiin uuden avaamisen jälkeen. Käytämme sitä yleensä sellaisten kirjastosymbolien lataamiseen, joita ei tunneta käännöshetkellä. Dlopen() on funktio, jota käytetään ohjelmissamme. DL-kirjasto toteuttaa dlopen(), joka on määritelty tiedostossa Dlfcn.h. Dlopen-funktiolle tarvitaan kaksi parametria: kirjastotiedoston nimi ja lippu. Tiedoston nimi on dynaaminen kirjasto, ja se määrittää, lasketaanko kirjaston riippuvuudet heti vai ei. Dlopen() palauttaa 'kahvan', jota tulisi pitää läpinäkymättömänä arvona ja muut DL-kirjastotoiminnot käyttävät tätä. Jos latausyritys epäonnistuu, dlopen() palauttaa arvon NULL. Mutta dlopen() palauttaa saman tiedostokahvan, jos se lataa saman kirjaston monta kertaa.

Dlopen-funktiota käyttäessään kääntäjä ei tutki mahdollisia virheitä, koska se ei ole tietoinen käyttämistämme tyypeistä ja prototyypeistä. Se ei näytä edistävän dlopen-toiminnon käyttöönottoa vakiolatauksessa, lukuun ottamatta muutamia pieniä tilanteita. Muuten, se on lähestymistapa itsetutkiskelun parantamiseen. Kun jaettua moduulia käyttää parhaillaan toinen ohjelma, muistin layoutin optimointi ei ole erityisen kiinnostunut ehdollisesta latauksesta. Muistin jalanjälki ei kasva, kun aiemmin käytetty kirjasto ladataan. Kääntäjän valvonnan välttäminen on vaarallista ja tekee virheiden kirjoittamisesta hyvää. Lisäksi meiltä puuttuu mahdollinen kääntäjän optimointi.

Esimerkki 1:

Tarkastellaan nyt seuraavaa esimerkkiä nähdäksesi dlopen-funktion toiminnallisuuden C-kielellä. Ensimmäisessä vaiheessa lataamme joitain C-standardikirjastoja. Täällä lataamme uuden kirjaston 'dlfcn.h', jota käytetään makrojen määrittämiseen dlopen-tilan argumentin rakentamisen aikana.







Sitten esittelemme toisen kirjaston ohjelmassamme 'gnu/lib-name.h'. Käyttäjäohjelmat löytävät GNU libc:n sisältämät jaetut kirjastotiedostot sen määrittelemien makrojen mukaan. GNU C -kirjasto tarjoaa peruskirjastot GNU- ja GNU/Linux-käyttöjärjestelmille sekä laajan valikoiman muita Linux-pohjaisia ​​järjestelmiä. Sen jälkeen meillä on päämenetelmän toteutus. Sen sisällä julistamme osoitinobjektin 'kahvaksi' void-avainsanalla. Ilmoitamme osoitinsinifunktion, jonka tietotyyppi on double. On olemassa toinen ilmoitus osoitinobjektista 'error' virheenkäsittelyä varten.



Tämän jälkeen kutsumme dlopen-funktion 'handle' -objektin sisällä. Dlopen ottaa kaksi argumenttia: LIBM_SO ja 'RTLD_LAZY'. Tässä 'LIBM_SO' on kirjastotiedoston nimi, joka tarjoaa matemaattisia funktioita, kuten trigonometrisiä funktioita. Tämä jaettu kirjasto tarvitaan, koska käytämme sinifunktiota. 'RTLD_LAZY' on toinen argumentti, joka kutsuu dlopen-funktiota. Kun tiettyyn symboliin viitataan ensimmäisen kerran, siirrot on suoritettava toteutuksen määräämänä aikana.



Koska prosessi ei välttämättä viittaa jokaiseen suoritettavan objektitiedoston symboliin, RTLD LAZY:n määrittämisen pitäisi parantaa suorituskykyä toteutuksissa, jotka mahdollistavat dynaamisen symbolien sitomisen. Seuraavaksi meillä on if-else-ehto virheenkäsittelylle, kun kahvaobjekti ei suorita dlopen-toimintoa. Soitamme dlerrorille virheen poistamiseksi.





Funktio dlerror() tarjoaa nollapääteisen merkkijonon, joka on ihmisen luettavissa, ja määrittää raportin viimeaikaisesta virheestä, joka on aiheutunut kutsusta johonkin dlopen API-kutsuun edellisen dlerror-kutsun jälkeen. Sitten heitämme funktion seuraavasti: '(*void**)(&sine)= dlsym(handle, sin)'. Koska tämä on outoa, valu on ISO C:n mukainen, mikä välttää kääntäjän varoitukset. Käytämme dlsym-funktiota, joka saa dynaamisen linkkimoduulin sisällä määritetyn symbolin polun, joka on käytettävissä dlopen()-funktion kautta.

Suoritamme myös if-else-toiminnon uudelleen vakiovirheelle, joka syntyy, kun dlerror() ei ole NULL. Sitten meillä on printf-lause, jossa määritämme laskettavan siniarvon. Viimeisessä vaiheessa suljemme kyseisen jaetun objektin kutsumalla dlclose-komentoa dlopen(:n) palauttamaa kahvaa varten.



#include
#include
#include
#include

int
pää ( int argc , hiiltyä ** argv )
{
mitätön * kahva ;
kaksinkertainen ( * heidän ) ( kaksinkertainen ) ;
hiiltyä * virhe ;

kahva = dlopen ( LIBM_SO , RTLD_LAZY ) ;
jos ( ! kahva ) {
fprintf ( stderr , '%s \n ' , dlerror ( ) ) ;
poistu ( EXIT_FAILURE ) ;
}
dlerror ( ) ;

* ( mitätön ** ) ( & heidän ) = dlsym ( kahva , 'ilman' ) ;

jos ( ( virhe = dlerror ( ) ) != TYHJÄ ) {
fprintf ( stderr , '%s \n ' , virhe ) ;
poistu ( EXIT_FAILURE ) ;
}

printf ( '%f \n ' , ( * heidän ) ( 4.0 ) ) ;
dlclose ( kahva ) ;
poistu ( EXIT_SUCCESS ) ;
}

Käytämme -ldl-vaihtoehtoa C-kääntämiskomennon kanssa, koska tämä on dlopen-linkitetyn käyttöliittymän kirjasto ja se on pakollinen. Kun dlopen-tiedosto suoritetaan, se näyttää aiemmin annetun arvon siniarvon.

Esimerkki 2:

Otetaan nyt toinen esimerkki dlopen-funktion käytöstä. Lataamme ohjelmaamme kaikki tarvittavat C-kirjastot dlopen-koodin toteuttamista varten. Sitten käynnistämme ohjelmamme päämenetelmän sisällä. Tässä määritämme merkkijonon muuttujan 'src' ilmoituksella. Ilmoitamme sitten osoitinmuuttujat 'strlen', 'handle' ja 'error'.

Seuraavaksi kutsumme kahvamuuttujaa ja otamme käyttöön dlopen-funktion. Dlopen-funktio syöttää jaetun kirjaston 'libstr.so' merkkijonojen käsittelyfunktioille ja lipun 'RTLD_LAZY', joka on jo esitelty edellisessä esimerkissä. Kutsumme dlerror-funktion 'error'-muuttujan sisällä poistamaan dlopen-funktion aiheuttaman virheen. Jos-else-komentoa käytetään virheiden tutkimiseen.

Sitten saamme strlen-funktion osoitteen dlsym-funktiolla ja tarkistamme virheet samalla. Tämän jälkeen kutsumme printf-funktiolla strnlen-funktiota palauttamaan annetun merkkijonon pituuden. Lopulta suljemme jaetun kirjaston dlclose-toiminnolla.

#include
#include
#include
#include
int pää ( mitätön )
{
hiiltyä * src = 'Hei Linux' ;
int ( * strlen ) ( konst hiiltyä * ) ;
mitätön * kahva ;
hiiltyä * virhe ;


kahva = dlopen ( './libstr.so' , RTLD_LAZY ) ;
virhe = dlerror ( ) ;
jos ( ! kahva || virhe != TYHJÄ ) { printf ( 'Kirjaston latausyritys epäonnistui! \n %s \n ' , virhe ) ;
palata - 1 ; }

strlen = dlsym ( kahva , 'strlen' ) ;
virhe = dlerror ( ) ;
jos ( ! strlen || virhe == TYHJÄ ) { printf ( '%s \n ' , virhe ) ; palata - 1 ; }

printf ( 'Jonon pituus on:%d \n ' , strlen ( src ) ) ;
dlclose ( kahva ) ;
palata 0 ;
}

Käytämme seuraavaa komentoa annetun ohjelman suorittamiseen. Tässä -lstr-lippua käytetään merkkijonon pituusfunktiolle ja ldl-merkkiä dlopen-kirjastotiedostolle. Käännetty ohjelma antaa merkkijonon pituuden, kuten kuoressa näkyy:

Johtopäätös

Tässä artikkelissa annetaan tietoja C-kielen dlopen-funktiosta. Meillä on lyhyt esittely dlopen-toiminnosta. Sitten toteutimme kaksi esimerkkiä. Funktio palauttaa tunnisteen, joka määrittää avatun kirjaston. Tämän tunnuksen ja dlsym-funktion avulla määritetään avatun kirjaston sisällä olevien funktioiden osoitteet. Kirjastossa olevan funktion osoite, joka on jo avattu dlopenilla, löytyy dlsym-funktiolla.