Sistem Dlopen Linux dalam C

Sistem Dlopen Linux Dalam C



Fungsi perpustakaan dlopen() ialah fungsi yang sangat berguna dalam bahasa C. Fungsi ini memuatkan perpustakaan ke dalam memori selepas membuka yang baharu. Kami biasanya menggunakannya untuk memuatkan simbol perpustakaan yang tidak diketahui pada masa penyusunan. Dlopen() ialah fungsi yang digunakan dalam program kami. Pustaka DL melaksanakan dlopen(), yang ditakrifkan dalam Dlfcn.h. Dua parameter diperlukan untuk fungsi dlopen: nama fail perpustakaan dan bendera. Nama fail ialah pustaka dinamik dan ia mentakrifkan sama ada kebergantungan pustaka dikira serta-merta atau tidak. Dlopen() mengembalikan 'pemegang' yang harus dianggap sebagai nilai legap dan operasi perpustakaan DL lain menggunakan ini. Jika percubaan untuk memuatkan tidak berjaya, dlopen() mengembalikan NULL. Tetapi dlopen() mengembalikan pemegang fail yang sama jika ia memuatkan perpustakaan yang sama berkali-kali.

Semasa menggunakan fungsi dlopen, pengkompil tidak memeriksa kemungkinan ralat kerana ia tidak mengetahui jenis dan prototaip yang kami gunakan. Penggunaan fungsi dlopen untuk pemuatan standard nampaknya tidak dipromosikan olehnya, kecuali untuk beberapa situasi kecil. By the way, ia adalah pendekatan untuk meningkatkan introspeksi. Apabila modul kongsi sedang digunakan oleh program lain, pengoptimuman susun atur memori tidak begitu berminat dengan pemuatan bersyarat. Jejak memori tidak meningkat apabila perpustakaan yang digunakan sebelum ini dimuatkan. Mengelakkan pemantauan pengkompil adalah berbahaya dan menjadikan penulisan pepijat yang baik. Selain itu, kami kekurangan pengoptimuman pengkompil yang mungkin.

Contoh 1:

Sekarang, pertimbangkan contoh berikut untuk melihat kefungsian fungsi dlopen dalam bahasa C. Dalam langkah pertama, kami memuatkan beberapa perpustakaan standard C. Di sini, kami memuatkan perpustakaan baharu 'dlfcn.h' yang digunakan untuk mentakrifkan makro semasa membina hujah mod dlopen.







Kemudian, kami memperkenalkan perpustakaan lain di dalam program kami 'gnu/lib-name.h'. Fail perpustakaan kongsi yang disertakan dengan GNU libc ditemui oleh program pengguna mengikut makro yang ditakrifkannya. Perpustakaan GNU C menawarkan perpustakaan asas untuk sistem pengendalian GNU dan GNU/Linux serta rangkaian luas sistem berasaskan Linux yang lain. Selepas itu, kami mempunyai pelaksanaan kaedah utama. Di dalamnya, kami mengisytiharkan objek penunjuk 'mengendalikan' dengan kata kunci tidak sah. Kami mengisytiharkan fungsi sinus penunjuk yang mempunyai jenis data berganda. Terdapat satu lagi pengisytiharan 'ralat' objek penunjuk untuk pengendalian ralat.



Selepas itu, kami menggunakan fungsi dlopen di dalam objek 'pemegang'. Dlopen mengambil dua hujah: LIBM_SO dan 'RTLD_LAZY'. Di sini, 'LIBM_SO' ialah nama fail perpustakaan yang menyediakan fungsi matematik seperti fungsi trigonometri. Pustaka kongsi ini diperlukan semasa kami menggunakan fungsi sinus. 'RTLD_LAZY' ialah satu lagi hujah yang memanggil fungsi dlopen. Apabila simbol yang diberikan dirujuk buat kali pertama, penempatan semula mesti dilakukan pada masa yang ditentukan oleh pelaksanaan.



Memandangkan proses mungkin tidak merujuk setiap simbol dalam fail objek boleh laku, menyatakan RTLD LAZY harus meningkatkan prestasi pada pelaksanaan yang membolehkan pengikatan simbol dinamik. Seterusnya, kita mempunyai syarat if-else untuk pengendalian ralat apabila objek pemegang gagal melaksanakan fungsi dlopen. Kami memanggil dlerror untuk mengosongkan ralat.





Fungsi dlerror() menyediakan rentetan yang ditamatkan nol yang boleh dibaca manusia dan menentukan pelaporan ralat terbaharu yang disebabkan oleh panggilan ke salah satu panggilan API dlopen sejak panggilan dlerror terakhir. Kemudian, kami menghantar fungsi seperti ini: '(*void**)(&sine)= dlsym(handle, sin)'. Oleh kerana ini pelik, pemutus mematuhi ISO C yang mengelakkan amaran daripada pengkompil. Kami menggunakan fungsi dlsym yang mendapat laluan simbol yang ditentukan di dalam modul pautan dinamik yang boleh diakses melalui fungsi dlopen().

Selain itu, kami melakukan operasi if-else sekali lagi untuk ralat standard yang dijana apabila dlerror() bukan NULL. Kemudian, kami mempunyai pernyataan printf di mana kami menentukan nilai sinus untuk dikira. Dalam langkah terakhir, kami menutup objek kongsi itu dengan menggunakan dlclose untuk pemegang yang dikembalikan oleh dlopen().



#include
#include
#include
#include

int
utama ( int argc , char ** argv )
{
batal * mengendalikan ;
berganda ( * mereka ) ( berganda ) ;
char * ralat ;

mengendalikan = dlopen ( LIBM_SO , RTLD_LAZY ) ;
jika ( ! mengendalikan ) {
fprintf ( stderr , '%s \n ' , dlerror ( ) ) ;
keluar ( EXIT_FAILURE ) ;
}
dlerror ( ) ;

* ( batal ** ) ( & mereka ) = dlsym ( mengendalikan , 'tanpa' ) ;

jika ( ( ralat = dlerror ( ) ) != NULL ) {
fprintf ( stderr , '%s \n ' , ralat ) ;
keluar ( EXIT_FAILURE ) ;
}

printf ( '%f \n ' , ( * mereka ) ( 4.0 ) ) ;
dtutup ( mengendalikan ) ;
keluar ( EXIT_SUCCESS ) ;
}

Kami menggunakan pilihan -ldl dengan arahan kompilasi C kerana ini adalah perpustakaan untuk antara muka terpaut dlopen dan ia diperlukan. Apabila pelaksanaan fail dlopen dibuat, ia memaparkan nilai sinus nilai yang diberikan sebelum ini.

Contoh 2:

Sekarang, kita ambil satu lagi contoh menggunakan fungsi dlopen. Kami memuatkan program kami dengan semua perpustakaan C yang diperlukan untuk pelaksanaan kod dlopen. Kemudian, kami memulakan program kami di dalam kaedah utama. Di sini, kami mentakrifkan rentetan dengan pengisytiharan pembolehubah 'src'. Kami kemudian mengisytiharkan pembolehubah penunjuk 'strlen', 'mengendalikan' dan 'ralat'.

Seterusnya, kami memanggil pembolehubah pemegang dan menggunakan fungsi dlopen. Fungsi dlopen memasukkan perpustakaan kongsi 'libstr.so' untuk fungsi pengendalian rentetan dan bendera 'RTLD_LAZY' yang telah ditunjukkan dalam contoh sebelumnya. Kami menggunakan fungsi dlerror di dalam pembolehubah 'ralat' untuk mengosongkan ralat yang dijana oleh fungsi dlopen. If-else digunakan untuk memeriksa ralat.

Kemudian, kami mendapatkan alamat fungsi strlen menggunakan fungsi dlsym dan mengesahkan ralat semasa melakukan ini. Selepas ini, kami menggunakan fungsi printf untuk memanggil fungsi strnlen untuk mengembalikan panjang rentetan yang diberikan. Pada akhirnya, kami menutup perpustakaan kongsi dengan fungsi dclose.

#include
#include
#include
#include
int utama ( batal )
{
char * src = 'Hello Linux' ;
int ( * strlen ) ( const char * ) ;
batal * mengendalikan ;
char * ralat ;


mengendalikan = dlopen ( './libstr.so' , RTLD_LAZY ) ;
ralat = dlerror ( ) ;
jika ( ! mengendalikan || ralat != NULL ) { printf ( 'Percubaan Memuatkan Perpustakaan Gagal! \n %s \n ' , ralat ) ;
kembali - 1 ; }

strlen = dlsym ( mengendalikan , 'strlen' ) ;
ralat = dlerror ( ) ;
jika ( ! strlen || ralat == NULL ) { printf ( '%s \n ' , ralat ) ; kembali - 1 ; }

printf ( 'Panjang Rentetan ialah:%d \n ' , strlen ( src ) ) ;
dtutup ( mengendalikan ) ;
kembali 0 ;
}

Kami menggunakan arahan berikut untuk pelaksanaan program yang diberikan. Di sini, bendera -lstr digunakan untuk fungsi panjang rentetan dan ldl digunakan untuk fail perpustakaan dlopen. Program yang disusun memberikan panjang rentetan seperti yang ditunjukkan dalam shell:

Kesimpulan

Maklumat disediakan mengenai fungsi dlopen bahasa C dalam artikel ini. Kami mempunyai pengenalan ringkas tentang fungsi dlopen. Kemudian, kami melaksanakan dua contoh. Fungsi ini mengembalikan pengecam yang mentakrifkan perpustakaan yang dibuka. Alamat fungsi di dalam perpustakaan yang dibuka kemudian ditentukan menggunakan pengecam ini dan fungsi dlsym. Alamat fungsi dalam perpustakaan yang telah dibuka menggunakan dlopen boleh didapati menggunakan fungsi dlsym.