Uptime: %95
Doluluk: %35 5 Ana Kategori 10 Alt kategoride Toplam:4.171 Dosya bulunmaktadır.
Dökümanlar
DLL leri Adres alanına Yüklemek
Dll?leri processlerin adres alanına yüklemek için 2 farklı yöntem vardır.
1-) Derleme Anında Yükleme
Belkide en çok kullanılan yöntemdir. Bu yöntemde, dll?lerin library dosyalarına ihtiyaç vardır. Siz derlerken, lib dosyasını programınıza eklersiniz, ve libdeki fonksiyonları istediğini gibi kullanırsınız. Daha sonra exe programınız çalıştırıldığında aynı isimli dll dosyayı aranır sistem tarafından , ve derlenirken kullanılan fonksiyonlar, bu dll içinden çağırılır. Yani sistem dll?I otomatik olarak process?in adres alanına yükler. Peki exe çalıştırıldıktan sonra sistem bu dll?I nerden bulup yükler :
Exe?nin çalıştığı dizin aranır
Process?in bulunduğu dizin aranır
Windows işletim sisteminin dizini
PATH ile tanımlanan tüm dizinler.
Eğer bu 4 arama şeklindede dll bulunamazsa işletim sistemi bir mesaj çıkartır , dll bulunamadı türünden bir mesaj verip, altta aradığı tüm dizinleri yazar.
2-) Çalışma Anında Yükleme
Bu yöntemde, exe fonksiyonunu kullanmadan hemen önce LoadLibrary(Ex) api?sini kullanarak istediği dll?I adres alanına yükler.Gerekli dll?in yüklenemediğini ise LoadLibrary api?sinin dönüş değerinden anlayabiliriz.
Şimdi bu apiyi inceleyelim :
Apinin biraz eski hali : HINSTANCE LoadLibrary(LPCTSTR lpszFileName);
Şimdi lpszFileName denilen kısım, yüklenecek dll?in ismi. Buraya pathide girebilirsiniz.
Geriye dönüş değeri ise dll?in yüklendiği adres alanın karşılığıdır. Eğer dll dosyası bulunamazsa NULL değeri döner. Peki neden NULL döner ? ( Cidden processlerin adres alanlarını bir ara anlatmalıyım sanırım, sebebi adres alanı ile ilgili )
Daha değişik bir hali : HINSTANCE LoadLibrayEx(LPCTSTR lpszFileName, HANDLE hFile, DWORD dwFlags);
HFile her zaman NULL olması gereken bir değer , neden ? çünkü microsoft bunu reserve etmiş kendine. Peki dwFlags nedir ? bu değer ile ilginç işler yaptırabiliriz.
Bu bayrak şu değerleri alabilir :
1. DON?T_RESOLVE_DLL_REFERENCE
Yuhh değere bak mı dediniz ? bir ara ms?in sabit değerlerinden bazılarını yazıyım, aklınız durur, adamlar değişken ismimi vermiş, yoksa hikayemi yazmış belli değil. Neyse, bu değer verilirse, sistem dll?deki DllMain fonksiyonunu çağırmaz. ( bu nedir demeyin sabredin ). Kısaca özetlemek gerekirse, dll bir process?e eklendiğinde , process dlldeki DllMain isimli bir fonksiyonu çağırır, tıpkı bir c programında main?in çağırılması gibi. Ama bunun çağırılmasını istemiyorsak bu değeri veririz. Bunun kötü bür yanı, eğer dll?iniz initialize kısmında, başka dllere ihtiyacı varsa, ve bunları DllMain de yüklüyorsa, onlarda yüklenmez.
2. LOAD_LIBRAY_AS_DATAFILE
Gene epey uzun vede kendini açıklayan bir değişken ismi. Çok kısa bir özet : Eğer dll dosyanızda, bitmap, icon vs gibi kaynaklar varsa sadece bunu kullanın, adı üstünde, hiçbir initialize?ini yapma, yer ayırma vs vs, sadece ekle bulunsun.
3. LOAD_WITH_ALTERED_SEARCH_PATH
Bunu neden kullanırlar pek bilmem. Yaptığı tek şey, yukarda bahsettiğim dll?I çağırıldığı zamanki arama sırasını değiştirir.
Bu arada not olarak birşey düşelim :
Dll?I yüklerken dosya ismi olarak gireceğiniz kısımda, uzantıyı eklemeyin yani bilmemne.dll gibi. Yoksa ilk önce registerydeki HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls deki dllerle karşılaştırılır.
Şimdi diyeceksiniz ki örnek ver : ( yada buraya kadar koptunuz yazıyı bıraktınız )
Registrynin bahsedilen o bölümünde şöyle bir kayt olsun :
Value name : abc
Value Data : c:\ceviz\xyz.dll
Şimdi sizde LoadLibrary(?abc?) dediniz. Sistem yukarılarda bir yerde bahsedilen sıraya göre gidip abc.dll dosyasını arar ve bulursa yükler.
Peki LoadLibrary(?abc.dll?) dersek ne olur. Uzantı bulundu, bu durumda registry?e bakılır. Registeryde abc diye bir value name görülür, ve c:\ceviz\xyz.dll yüklenir, yani alakasız bir dll?
Gene yukarılarda bir yerde dll?I unmap etmek yada kovmak diye birşeyden bahsettik ya, işte oda FreeLibrary(HINSTANCE hInst) ile yapılır.
LoadLibraryden dönen hInst değerini bu apiye parametre olarak verirseniz, dll sizin adres alanınızdan çıkartılır. Ama tekrar uyarı, dll?in yarattığı dinamik alanlar otomatik olarak silinmez, process?in bunları silmesi beklenir.
Şimdi biraz teknik detaya girelim.
Windows işletim sisteminde kernel objelerinde birer kullanım adedi gibi bir ek bulunur. Şimdi siz LoadLibrary diyerek bir dll yüklediğinizde , bu dll?e ait kullanım sayısı 1 artırılarak yükleme gerçekleştirilir. Eğer process ikinci kez aynı dll?I yüklemeye çalışırsa, sistem sadece kullanım sayısını 1 artırır ama yeniden yüklemez. Yeni sürekli Loadlibrary diyerek pratikte hafızanızı şişiremezsiniz.
Peki FreeLibrary?I çağırdığınızda ne olur. Bu seferde kullanım sayısı 1 azaltılır. Eğer kullanım sayısı sıfıra ulaşırsa, dll , o processten ayrılır. Kullanım sayısı sıfır oldugu halde freelibrary yazarsanız da hata alırsınız.
Bu arada bu kullanım sayısı, process bazındadır. Yani başka bir process o dll?I yüklerse kullanım sayısı o process?te bağımsızdır.
Peki multithread çalışan bir sistemde, bir thread kullanacağı dll?in başka bir dll tarafından yüklenip yüklenmediğini nasıl anlayaibilir ?
GetModuleHandle apisini kullanabilir .
Örnek :
HINSTANCE hInst = GetModuleHandle(?abc?);
If (NULL == hInst ) ise yüklenmemiş
Bu arada GetModuleFileName vede FreeLibraryAndExitThread apilerini helpten bir bakın derim.
Özellikle FreeLibraryAndExitThread çok ilginç bir api. Böyle bir api sizce neden yapıldı ?. Yaptığı tek iş, aslında dll?in unmap edip o threadden çıkmak olan bir api neden gerekir ? Merak eden varsa, foruma sorarsa cevaplanır elbette.
Bu Döküman Hakkında Ne Düşünüyorsunuz?
Bu Döküman İçin Yorum Yapılmadı. İlk Olmak İster misin?