|
WinAPI Fonksiyonlarının C#'ta Kullanımı |
|
Gönderiliyor lütfen bekleyin... |
|
|
C# ve dotNET ile
birlikte yazılım geliştirmeye yeni bir soluk gelmiş olsada C# ile eskiden yazılmış
COM komponentlerine erişebilmek mümkündür. Daha önceki iki makalede .NET ve
COM ilişkisini detaylı bir şekilde incelemiştik. Bu makalede .NET'in Win 32
API ile nasıl entegre edildiği anlatılacaktır. .NET ve C#'ın yeni imkanlarının
yanısıra eski bir teknoloji olan COM ve yönetilmeyen(unmanaged) kodlarla uyumlu
bir şekilde çalışması belkide C# ve .NET'i diğer yazılım geliştirme platformlarından
ayıran en önemli özelliktir.
Bildiğiniz gibi C#'ta gösterici kullanımı tamamen serbesttir. Bu yüzden eskiden(.NET
öncesi) yazılmış ve parametre olarak gösterici alan COM komponentleri ve Windows
API fonksiyonları C# ile sorunsuz bir şekilde çalıştırılabilmektedir. Bu yazıda
Win API fonksiyonlarının .NET ortamında ne şekilde ele alındığı incelenecektir.
Win32 sistem fonksiyonları kullanıldığında, kod CLR tarafından yönetilmekten
çıkar. .NET ortamında geliştirilen bir uygulamada yönetilmeyen kod segmenti
ile kaşılaşılırsa ilgi kod segmenti CLR tarafından yönetilmekten çıkar. Dolayısıyla
"garbage collection" mekanizması ve .NET'e özgü diğer servisler kullanım
dışı olur.
CLR tarafından yönetilmeyen kodlara erişebilmek için C#'ta System.Runtime.InteropServices
isim alanında bulunan ve DllImprtAttribute sınıfını temsil eden DllImport
niteliği kullanılmaktadır. DllImport niteliği ile harici bir kaynakta bulunan
metoda referans vermek için external anahtar sözcüğü kullanılır. Bir
sınıf bildiriminin en başında external anahtar sözcüğü ve DllImport niteliği
kullanılarak CLR tarafından yönetilmeyen bir metot bildirimi yapılır. Tabi metodun
gövdesi harici bir kaynakta zaten var olduğu için bizim metodun gövdesini yazmamızın
bir anlamı yoktur. Ardından bu metot sınıfın istenildiği yerinde kullanılabilir.
İsterseniz basit bir örnekle DllImport niteliğinin kullanımını gösterelim.
Win API windows sistemlerinin programlanabilir arayüzünü içermektedir. Windows
uygulamarının tamamı bu arayüzdeki fonksiyonları ve diğer yapıları kullanmaktadır.
Aşağıdaki programda Win32 sistemlerinde bulunan MessageBox() fonksiyonunun kullanımına
bir örnek verilmiştir.
Not : Bu yazıda C#'ta niteliklerin(Attributes) nasıl kullanıldığını
bildiğiniz varsayılmıştır.
using
System;
using System.Runtime.InteropServices;
class
Class1
{
[DllImport("user32.dll")]
public static extern int
MessageBox(int tip,string
mesaj,string baslik,int
secenek);
static
void Main()
{
MessageBox(0,"Mesaj","Win
API MessageBox",2);
}
}
|
DllImportAttribute
sınıfının bir tane yapıcı metodu bulunmaktadır. Bu metot parametre olarak harici
kaynağın adı belirtmektedir. Yukarıdaki kaynak kodda MessageBox fonksiyonunun
bulunduğu "user32.dll" isimli dosya DllImport niteliğine parametre
olarak verilmiştir. Bu örnekte dikkat edilmesi gereken diğer nokta ise extern
anahtar sözcüğünün kullanımıdır. Bu anahtar sözcük ile bildirimi yapılan metodun
harici bir dosyada olduğu belirtilmektedir. Dolayısıyla C# derleyicisi metodun
gövdesini kaynak kodda aramayacaktır.
Programın çalışma şeklini açıklamadan önce ekran çıktısına bakalım :
Yukurıdaki çıktıdan ve kaynak koddan da görüldüğü üzere Win API deki bir fonksiyonun
çağrımı klasik metot çağrımından farklı değildir. Değişen tek şey metodun bildirim
şeklidir.
Not : Gösterilen mesaj kutusunun farklı formlarını görmek için MessageBox
metodunun parametreleri ile oynayın.
Şimdi kısaca yukarıdaki programın çalışma zamanındaki durumunu inceleyelim.
Program çalıştırıldığında, CLR tarafından yönetilmeyen bir metot çağrımı yapıldığında
ilgili kaynaktan metot belleğe yüklenir ve belleğe yüklenen metodun başlangıç
adresi saklanır. Ardından bizim parametre olarak geçtiğimiz değişkenler DLL'
deki fonksiyona uyumlu hale getirilir ve parametre olarak geçirilir. Eğer bir
geri dönüş değeri bekleniyorsa yönetilmeyen kod bölümünden gelen değer uygun
.NET türüne dönüştürülerek işlemlere devam edilir. Bu işlemler tamamen .NET'in
alt yapısını ilgilendirmektedir. Dolayısıyla programcının yapacağı iş sadece
metodun bildirimini doğru bir şekilde gerçekleştirmektir.
DllImportAttribute sınıfının bir kaç önemli özelliği daha vardır. Bunlardan
en önemlisi harici kaynaktaki bir fonksiyona takma isim verebilmemizi sağlayan
string türünde olan EntryPoint özelliğidir. EntryPoint özelliğini kullanarak
MessagBox fonksiyonuna takma isim verebiliriz. Fonksiyon çağrımı bu takma isim
ile gerçekleştirilebilmektedir. Örneğin MessageBox fonksiyonuna TebrikMesajiVer
şeklinde bir takma isim vermek için aşağıdaki gibi bir bildirim yapılmalıdır.
using
System;
using System.Runtime.InteropServices;
class
Class1
{
[DllImport("user32.dll",EntryPoint =
"MessageBox")]
public static extern int
TebrikMesajiVer(int tip,string
mesaj,string baslik,int
secenek);
static
void Main()
{
TebrikMesajiVer(0,"Tebrikler","Takma
İsim Verme",0);
}
}
|
Şimdi de DllImport niteliği ile ilgili diğer özelliklere ve önemli noktalara
bakalım.
1 - DllImport niteliği yalnızca metotlara uygulanabilir.
2 - DllImport niteliği ile işaretlenmiş metotlar mutlaka extern
anahtar sözcüğü ile bildirilmelidir.
3 - DllImport niteliğinin EntryPoint'in haricinde 4 tane isimli parametresi(named
parameter) daha vardır. Bunlar : CallingConvention, CharSet, ExactSpelling,
PreserveSig ve SetLastError parametreleridir. Bu parametrelerden önemli
olanlar aşağıda açıklanmıştır.
4 - CallingConvention : Bu paramtre CallingConvention numaralandırması
türündendir. Bu parametre ile harici metodun ne şekilde çağrılacağı ile ilgili
bilgi verilir. CallingConvention numaralandırması 5 tane sembol içerir. Varsayılan
olarak bu sembol Winapi olacak şekilde ayarlanmıştır. Yani CallingConvention
parametresini DllImport ile kullanmıyorsak varsayılan olarak bu Winapi'dir.
Diğer semboller ise Cdecl, FastCall, ThisCall, StdCall şeklindedir. En
çok Winapi sembolu kullanıldığı için diğer sembollerin ne anlama geldiği anlatılmayacaktır.
Diğer sembollerin ne anlama geldiklerini MSDN kütüphanesinden detaylı bir şekilde
öğrenebilirsiniz.
5 - CharSet : Harici fonksiyonun çağrımında kullanılacak karekter
setini belirler. Bu parametre CharSet numaralandırması ile belirtilir. Varsayılan
olarak CharSet.Auto şeklindedir. CharSet numaralandırmasının diğer sembolleri
Ansi, Unicode ve None şeklindedir.
6 - ExactSpelling
: EntryPoint ile belirtilen ismin ilgili fonksiyon ismine yazım biçimi bakımından
tam uyumlu olup olmayacağını belirtir. Bu özellik bool türündendir ve varsayılan
olarak false değerdir.
DllImport metodunun varsayılan çağrım biçimi olan Winapi sadece Windows sistemlerine
özgün olduğu için sistemler arası taşınabilirliğin yüksek olması gereken projelerde
bu niteliğin kullanımından kaçınmak gerekir. Bu yüzden DllImport özelliğini
kullanmadan önce ilgili fonksiyonun .NET Framework içinde olup olmadığını kontrol
etmek gerekir. Örneğin MessageBox fonksiyonu zaten System.Windows.Forms isim
alanında bulunduğu için API kullanarak bu fonksiyondan yararlanmak mantıklı
değildir. Zira ileride programınızın Linux ortamında yada diğer farklı ortamlarda
da çalışmasını istiyorsanız programınızı değiştirip yeniden derlemeniz gerekecektir.
Oysa .NET Framework içinde bulunan standart sınıfları ve onların metotlarını
kullanırsanız böyle bir derdiniz olmayacaktır.
Makale:
WinAPI Fonksiyonlarının C#'ta Kullanımı C#, Visual C# ve .NET Sefer Algan
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|