Geri git   Van.GEN.TR Forum | Yerel Van Forumu > Bilgisayar > Programlama > Visual Basic, Delphi, C++ Ve Diğer Diller

Cevapla
 
Konu Araçları Stil
Alt 15/12/07, 12:59   #1
Bur2
Korgeneral
 
Bur2 - ait Kullanıcı Resmi (Avatar)
 
Üyelik tarihi: Oct 2007
Bulunduğu yer: evde :)
Yaş: 45
Mesajlar: 2.544
Tecrübe Puanı: 50 Bur2 has a reputation beyond repute Bur2 has a reputation beyond repute Bur2 has a reputation beyond repute Bur2 has a reputation beyond repute Bur2 has a reputation beyond repute Bur2 has a reputation beyond repute Bur2 has a reputation beyond repute Bur2 has a reputation beyond repute Bur2 has a reputation beyond repute Bur2 has a reputation beyond repute Bur2 has a reputation beyond repute
Standart Dinamik bağlama kütüphaneleri DLL'ler

DLL
Dinamik bağlama kütüphaneleri ( dll ), windows işletim sistemi ile birlikte programlamada çok önemli bir yere oturmuştur. Windows işletim sisteminde birçok önemli fonksiyon dll’lere dağıtılmıştır. Örnek olarak : Kernel32.dll : hafıza ile ilgili işlemler, User32.dll : pencere yaratımı, mesajlaşma vs.



Dll’leri yaratmak
İnanın bir dll yazmak, bir program yazmaktan daha kolaydır. Bir takım sentaks kurallarına uyarak yazdığınız programınızı linker da birleştirirken sadece /DLL anahtarını kullanırsınız.

Bir program, bir dlldeki fonksiyon/ları kullanacağı zaman ilk önce , bu dll’i kendi adres alanına yüklemelidir. Bu 2 tane yöntemle yapılır, yöntemlerin isimleri çok önemli değil ama biri derleme anı ekleme, biri çalışma anı ekleme diyebiliriz. Ama her iki yöntemde de fonksiyonu kullanmadan önce dll mutlaka adres alanına yüklenmeli. ( Bu adres alanları ,process vs ilgili yazı isteyen olursa istekte bulunursa sevinirim ).

Dll, prosessin adres alanına yüklendikten sonra, artık dll ‘e ait fonksiyonlar, sanki programınızın içindeki sıradan fonksiyonlardan biriymiş gibi kullanabilirsiniz. Hatta threadleriniz bu fonksiyonların bir dll’den geldiğini bile anlamayabilir. Kendi fonksiyonunuz , dll’deki bir fonksiyonu çağırdığında, fonksiyona göndermek istediği parametreleri stack (yığıt) alanına basar. Daha sonra dll’deki fonksiyon çalışırken yığıttan ilgili parametreleri çekerek, hangi parametrelerler çalışması gerektiğini anlar. Buradan anlaşılması gereken nokta, dll ile process veya thread aynı yığıt alanını kullanır. Dll’lerdeki fonksiyonlarınız bir bellek alanı ayırıyorsa, bunuda kendisinin eklendiği process’in bellek alanından ayırır. Mesela, diyelimki dll’deki bir fonksiyon dinamik bir alan tahsis etti, sonrada processinizden bu dll’I unmap ettiniz ( şimdilik bunu dll’I kovmak olarak düşünün ), bu dinamik alan gidermi ? Hayır, gitmez, çünkü bu adres bölümü processin adres bölümünde ayrılmıştır ve process yok edene dek veya processin kendisi yok olana dek orada duracaktır.

Peki Dll’imizde global değişkenler tanıttık diyelim, ve birden fazla process bu dll’I kendisine bağladı, bu global değişkenler ne olur ? . Aslında sorumuzun cevabı yukarda var. Her dll, kendisini bağlayan process’in adres alanına yüklenir, dolayısıyla global nesneleri, o adres alanında global olur, başka bir process’de bu dll’I bağlarsa onun global değişkenleri bağımsız olur.

Aslında biraz değişik yöntemlerle, bazı değişkenlerin bir dll’de statik yapmak mümkün. Yani ne kadar başka process’e yüklenirse yüklensin bu statik alanlar birbirlerini etkileyecek şekilde ayarlanabilir. Bunun örneğini daha sonra göreceğiz.



Dll’I 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\Contro l\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 Adresi (link) Görme Yetkiniz Yok BEDAVA'ya Üye Ol Sitemizden Faydalan....]

[Bu Adresi (link) Görme Yetkiniz Yok BEDAVA'ya Üye Ol Sitemizden Faydalan....]


Bur2 isimli Üye şimdilik offline konumundadır   Alıntı ile Cevapla
Konu Sayısı: 497
Takımınız:
Alt 31/07/08, 15:28   #2
Neutralizer
Yasaklı kullanıcı
 
Neutralizer - ait Kullanıcı Resmi (Avatar)
 
Üyelik tarihi: Jan 2008
Bulunduğu yer: İstediğin yerden
Mesajlar: 1.883
Tecrübe Puanı: 0 Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute
Standart

paylaşım için tşkrlr
Neutralizer isimli Üye şimdilik offline konumundadır   Alıntı ile Cevapla
Konu Sayısı: 316
Takımınız:
Cevapla


Konuyu Toplam 1 Üye okuyor. (0 Kayıtlı üye ve 1 Misafir)
 

Yetkileriniz
Yeni Mesaj yazma yetkiniz Aktif değil dir.
Mesajlara Cevap verme yetkiniz aktif değil dir.
Eklenti ekleme yetkiniz Aktif değil dir.
Kendi Mesajınızı değiştirme yetkiniz Aktif değildir dir.

BB code is Açık
Smileler Açık
[IMG] Kodları Açık
HTML-KodlarıKapalı
Gitmek istediğiniz klasörü seçiniz


Bütün Zaman Ayarları WEZ +3 olarak düzenlenmiştir. Şu Anki Saat: 22:02 .


Powered by vBulletin
Copyright © 2000-2007 Jelsoft Enterprises Limited.
Sitemap
6, 5, 3, 7, 8, 9, 10, 11, 12, 13, 14, 15, 113, 16, 17, 18, 19, 81, 20, 27, 22, 23, 24, 25, 26, 48, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 43, 136, 40, 58, 45, 42, 44, 46, 47, 53, 54, 55, 56, 57, 59, 60, 70, 61, 62, 63, 64, 65, 66, 68, 69, 71, 72, 74, 75, 76, 77, 78, 79, 80, 82, 83, 96, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 98, 97, 100, 101, 102, 103, 106, 104, 105, 112, 109, 108, 107, 110, 111, 114, 115, 118, 116, 117, 119, 148, 154, 124, 165, 122, 120, 123, 121, 150, 153, 125, 128, 129, 131, 132, 133, 134, 135, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 151, 149, 202, 175, 164, 152, 167, 155, 156, 157, 158, 159, 160, 161, 162, 163, 195, 169, 166, 168, 170, 171, 172, 199, 174, 173, 196, 200, 176, 177, 180, 178, 179, 182, 189, 187, 184, 186, 191, 192, 193, 194, 197, 198, 201, 203, 229, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 236, 231, 232, 233, 234, 235, 237, 240, 239, 241, 243, 242, 244,