C'de Linux Dlopen Sistemi

C De Linux Dlopen Sistemi



Kütüphane işlevi dlopen(), C dilinde çok kullanışlı bir işlevdir. İşlev, yenisini açtıktan sonra kütüphaneyi belleğe yükler. Genellikle derleme zamanında bilinmeyen kütüphane sembollerini yüklemek için kullanırız. Dlopen(), programlarımızda kullanılan bir fonksiyondur. DL kitaplığı, Dlfcn.h'de tanımlanan dlopen()'i uygular. dlopen işlevi için iki parametre gereklidir: kitaplık dosyasının adı ve bayrak. Dosyanın adı dinamik bir kitaplıktır ve kitaplığın bağımlılıklarının hemen hesaplanıp hesaplanmayacağını tanımlar. dlopen(), opak bir değer olarak kabul edilmesi gereken bir 'tutamaç' döndürür ve diğer DL kitaplığı işlemleri bunu kullanır. Yükleme girişimi başarısız olursa, dlopen() NULL değerini döndürür. Ancak, aynı kitaplığı birçok kez yüklerse, dlopen() aynı dosya tanıtıcısını döndürür.

Derleyici, dlopen işlevini kullanırken, kullandığımız tür ve prototiplerin farkında olmadığı için olası hataları incelemez. Standart yükleme için dlopen işlevinin konuşlandırılması, birkaç küçük durum dışında, onun tarafından desteklenmiyor gibi görünüyor. Bu arada, iç gözlemi geliştirmek için bir yaklaşım. Paylaşılan modül şu anda başka bir program tarafından kullanıldığında, bellek yerleşimi optimizasyonu özellikle koşullu yüklemeyle ilgilenmez. Daha önce kullanılan bir kitaplık yüklendiğinde bellek ayak izi artmaz. Derleyici izlemesinden kaçınmak tehlikelidir ve iyi bir hata yazımı sağlar. Ek olarak, olası derleyici optimizasyonundan da yoksunuz.

Örnek 1:

Şimdi, C dilinde dlopen işlevinin işlevselliğini görmek için aşağıdaki örneği göz önünde bulundurun. İlk adımda, bazı C standart kitaplıkları yüklüyoruz. Burada, dlopen modu argümanını oluştururken makroları tanımlamak için kullanılan yeni kütüphane “dlfcn.h”yi yüklüyoruz.







Ardından “gnu/lib-name.h” programımızın içinde başka bir kütüphane tanıtıyoruz. GNU libc'nin içerdiği paylaşılan kitaplık dosyaları, tanımladığı makrolara göre kullanıcı programları tarafından bulunur. GNU C Kitaplığı, GNU ve GNU/Linux işletim sistemlerinin yanı sıra çok çeşitli diğer Linux tabanlı sistemler için temel kitaplıkları sunar. Bundan sonra, ana yöntem uygulamasına sahibiz. Bunun içinde, void anahtar sözcüğüyle işaretçi nesnesini “handle” ilan ederiz. Double veri tipine sahip bir işaretçi sinüs işlevi ilan ediyoruz. Hata işleme için başka bir işaretçi nesnesi “error” bildirimi vardır.



Bundan sonra, “handle” nesnesinin içindeki dlopen işlevini çağırıyoruz. Dlopen iki argüman alır: LIBM_SO ve “RTLD_LAZY”. Burada “LIBM_SO” trigonometrik fonksiyonlar gibi matematiksel fonksiyonları sağlayan kütüphane dosyasının adıdır. Sinüs işlevini kullandığımız için bu paylaşılan kitaplık gereklidir. “RTLD_LAZY”, dlopen işlevini çağıran başka bir argümandır. Belirli bir sembole ilk kez başvurulduğunda, uygulama tarafından belirlenen bir zamanda yer değiştirme yapılmalıdır.



Bir işlem, yürütülebilir bir nesne dosyasındaki her sembole referans vermeyebileceğinden, RTLD LAZY'nin belirtilmesi, dinamik sembol bağlamayı etkinleştiren uygulamalardaki performansı artırmalıdır. Ardından, tutamaç nesnesi dlopen işlevini gerçekleştiremediğinde hata işleme için bir if-else koşulumuz var. Hatayı temizlemek için dlerror'ı çağırırız.





dlerror() işlevi, insan tarafından okunabilen ve son dlerror çağrısından bu yana dlopen API çağrılarından birine yapılan çağrının neden olduğu son hatanın raporlanmasını belirten boş sonlandırılmış bir dize sağlar. Ardından fonksiyonu şu şekilde oluşturuyoruz: “(*void**)(&sine)= dlsym(handle, sin)”. Bu garip olduğu için, döküm, derleyiciden gelen uyarıları önleyen ISO C ile uyumludur. Bir dlopen() işlevi aracılığıyla erişilebilen bir dinamik bağlantı modülü içinde belirtilen bir sembolün yolunu alan dlsym işlevini kullanıyoruz.

Ayrıca dlerror() NULL olmadığında oluşan standart hata için if-else işlemini tekrar yapıyoruz. Ardından, hesaplanacak sinüs değerini belirttiğimiz bir printf ifademiz var. Son adımda, dlopen() tarafından döndürülen tanıtıcı için dlclose'yi çağırarak bu paylaşılan nesneyi kapatıyoruz.



#include
#include
#include
#include

int
ana ( int argc , karakter ** bağımsız değişken )
{
geçersiz * üstesinden gelmek ;
çift ( * onların ) ( çift ) ;
karakter * hata ;

üstesinden gelmek = dlopen ( LIBM_SO , RTLD_LAZY ) ;
eğer ( ! üstesinden gelmek ) {
fprintf ( standart , '%s \n ' , hata ( ) ) ;
çıkış ( EXIT_FAILURE ) ;
}
hata ( ) ;

* ( geçersiz ** ) ( & onların ) = dlsym ( üstesinden gelmek , 'olmadan' ) ;

eğer ( ( hata = hata ( ) ) != HÜKÜMSÜZ ) {
fprintf ( standart , '%s \n ' , hata ) ;
çıkış ( EXIT_FAILURE ) ;
}

baskı ( '%f \n ' , ( * onların ) ( 4.0 ) ) ;
dlclose ( üstesinden gelmek ) ;
çıkış ( EXIT_SUCCESS ) ;
}

-ldl seçeneğini C derleme komutuyla kullanıyoruz çünkü bu dlopen bağlantılı arabirim için kitaplıktır ve gereklidir. Dlopen dosyasının çalıştırılması yapıldığında daha önce verilen değerin sinüs değerini gösterir.

Örnek 2:

Şimdi, dlopen işlevini kullanmanın başka bir örneğini alıyoruz. Programımızı dlopen kodunun uygulanması için gerekli tüm C kitaplıklarıyla yüklüyoruz. Ardından main method içinde programımızı başlatıyoruz. Burada “src” değişkeninin bildirimi ile stringi tanımlıyoruz. Ardından “strlen”, “handle” ve “error” işaretçi değişkenlerini bildiririz.

Ardından, handle değişkenini çağırır ve dlopen işlevini dağıtırız. Dlopen işlevi, dize işleme işlevleri için paylaşılan 'libstr.so' kitaplığını ve önceki örnekte zaten gösterilen 'RTLD_LAZY' bayrağını girer. Dlopen işlevi tarafından üretilen hatayı temizlemek için “error” değişkeninin içindeki dlerror işlevini çağırıyoruz. Hataları incelemek için if-else kullanılır.

Daha sonra dlsym fonksiyonunu kullanarak strlen fonksiyonunun adresini alıyoruz ve bunu yaparken hataları doğruluyoruz. Bundan sonra, verilen dizenin uzunluğunu döndürmek için strnlen işlevini çağırmak için printf işlevini kullanırız. Son olarak dlclose fonksiyonu ile paylaşılan kütüphaneyi kapatıyoruz.

#include
#include
#include
#include
int ana ( geçersiz )
{
karakter * kaynak = 'Merhaba Linux' ;
int ( * strlen ) ( const karakter * ) ;
geçersiz * üstesinden gelmek ;
karakter * hata ;


üstesinden gelmek = dlopen ( './libstr.so' , RTLD_LAZY ) ;
hata = hata ( ) ;
eğer ( ! üstesinden gelmek || hata != HÜKÜMSÜZ ) { baskı ( 'Kitaplık Yükleme Denemesi Başarısız! \n %s \n ' , hata ) ;
dönüş - 1 ; }

strlen = dlsym ( üstesinden gelmek , 'strlen' ) ;
hata = hata ( ) ;
eğer ( ! strlen || hata == HÜKÜMSÜZ ) { baskı ( '%s \n ' , hata ) ; dönüş - 1 ; }

baskı ( 'Dizenin Uzunluğu:%d \n ' , strlen ( kaynak ) ) ;
dlclose ( üstesinden gelmek ) ;
dönüş 0 ;
}

Verilen programın yürütülmesi için aşağıdaki komutu kullanıyoruz. Burada, -lstr bayrağı, dize uzunluğu işlevi için kullanılır ve ldl, dlopen kitaplık dosyası için kullanılır. Derlenen program, kabukta gösterildiği gibi dizenin uzunluğunu verir:

Çözüm

Bu yazıda C dilinin dlopen işlevi ile ilgili bilgiler verilmektedir. Dlopen işlevine kısa bir giriş yaptık. Ardından iki örnek uyguladık. İşlev, açılan kitaplığı tanımlayan bir tanımlayıcı döndürür. Açılan kütüphane içindeki fonksiyonların adresleri daha sonra bu tanımlayıcı ve dlsym fonksiyonu kullanılarak belirlenir. Daha önce dlopen kullanılarak açılmış bir kütüphane içindeki bir fonksiyonun adresi, dlsym fonksiyonu kullanılarak bulunabilir.