C# Komut Satırı Derleyicisi(csc.exe)
C# Komut Satırı Derleyicisi(csc.exe) ve Parametreleri
Bu yazıda sizlere önemli bir referans kaynağı olacağını düşündüğüm C# komut satırı derleyicisinin özelliklerini ve parametrelerini bir arada inceleyeceğiz. Böyle bir kaynağı oluşturmamdaki sebep C# komut derleyiciisnin kullanımı ile ilgili bana gelen onlarca e-postaya toplu olarak cevap verebilmek.
Bildiğiniz üzere .NET ortamında etkili bir şekilde geliştirme yapabilmek için Visual Studio.NET aracına ihtiyaç duyuyoruz. Ancak bu geliştirme ortamı olmadan da her tür .NET uygulamasını geliştirme imkanına sahibiz. Bu imkanı sağlayan en önemli araç elbetteki C#’ın komut satırından da çalışan csc.exe isimli derleyicisidir. C# komut satırı derleyicisi .NET Framework SDK ile birlikte ücretsiz olarak dağıtılmaktadır. Dolayısıyla .NET ortamında uygulama geliştirmek için yapmamız gereken tek şey www.microsoft.com sitesinden .NET Farmework SDK’nın son sürümünü bilgisayarınıza indirmek ve kurmaktır.
C# derleyicisi komut satırından basitçe kullanılabilmektedir. C# derleyicisini komut satırından en etkili bir şekilde kullanabilmek için işletim sisteminizde bir takım ayarlar yapmanız gerekmektedir. Örneğin siz komut satırında herhangi bir dizin içerisindeyken bile csc.exe çalıştırılabilir dosyasını çalıştırabilmeniz için csc.exe dosyasının bulunduğu dizini sistem özelliklerinde tanımlamanız gerekmektedir. Bu işlemi yapmak için kontrol panelden system ikonunu ve ardından advanced sekmesini aşağıdaki gibi seçin.
Advanced sekmesine geçtikten sonra yukarıdaki şekilde kırmızı ile işaretlenen “Environment Variables” düğmesine tıklayın.(Kullandığınız işletim sistemine göre bu butonun yeri değişik olabilir. Yukarıdaki ekran görüntüsü Windows XP işletim sistemine aittir.) Karşınıza çıkacak olan aşağıdaki ekrandan “System Variables” alanından Path seçeneğini seçin.
Path seçecenği tıklanarak açılan penceredeki Variable value alanının sonuna ; karakterini ekledikten sonra csc.exe dosyasının bulunduğu dizini yazın. csc.exe dosyası kullandığınız işletim sistemini göre değişiklik gösterebilir ancak genellikle aşağıdaki gibidir.
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322
Son dizin kullandığınız Framework’un versiyon numarasını göstermektedir.
Yukarıdaki işlemlerin doğru bir şekilde tamamlandığını kontrol etmek için komut satırını açın ve “csc” yazın. Eğer aşağıdaki hata ile karşılaşıyorsanız işlemleriniz başarı ile gerçekleşmiş demektir.
Bu hatanın sebebi csc.exe programına derlenecek dosyayı parametre olarak vermememizdir.
Derleme İşlemi
csc.exe ile en basit derleme işlemi bir girdi dosya ve çıktı dosya belirtme ile yapılır. Örneğin kaynakkod.cs dosyasını Program.exe şeklinde derlemek için aşağıdaki komutu çalıştırmamız yeterlidir.
> csc kaynakkod.cs /out:Program.exe
Eğer out parametresini kullanmayıp komutu
> csc kaynakkod.cs
şeklinde çalıştırsaydık derleme işlemi başarılı olurdu ancak oluşturulan çalıştırılabilir dosyanın adı kaynakkod.exe olurdu.
Proje Tipleri ve target parametresi
.NET ortamında birden fazla proje tipi vardır ve dolayısıyla her bir proje tipinin derleme biçimi farklıdır. Örneğin bir önceki komutumuz derlem işlemini bir konsol uygulamasına göre yapacaktır. Esasında csc.exe derleyicisnin varsayılan derleme biçimide budur. Eğer derleme işlemini farklı uygulama tipleri için yapacak olursak derşeyicinin target parametresini kullanmamız gerekir. Örneğin kaynak kodumuzu bir windows uygulaması olacak şekilde derlemek istiyorsak derleme komutu aşağıdaki gibi olmalıdır.
> csc kaynakkod.cs /target:winexe /out:Program.exe
yada
> csc kaynakkod.cs /t:winexe /out:Program.exe
Eğer kaynak kodumuzu çalıştırılabilir bir uygulama yerine bir kütüphane dosyası olacak şekilde derlemek istiyorsak aşağıdaki komutu kullanmalıyız.
> csc kaynakkod.cs /target:library /out:Program.exe
Diğer bir derleme biçimi ise modül derlemesidir. Modüller içinde manifest dediğimiz metadataları olmayan yalnızca kod bilgilerini içeren dosyalardır. Modüller çalıştırılabilir değildir. Dolayısıyla modüller ancak manifest bilgisi olan başka bir derlenmiş kütüphaneye eklenmek için kullanılabilir. Modül şeklind derleme için aşağıdaki kmut kullanılmalıdır.
> csc kaynakkod.cs /target:module /out:Program.exe
Referans Bilgileri ve Response Dosyaları
csc.exe derleyicisi derleme işlemini başarı ile gerçekleştriebilmesi için bazı kütüphanelere ihtiyaç duyar. Bu kütüphaneler assembly dosyaları içinde barındırılmıştır. Bu kütüphanalerin projemizde kullanıldığını belirtmek için reference parametresi kullanılır. Eğer referans vermeniz gereken assembly dosyaları fazla ise bu işi otomatikleştirmek için response. dosyaları kullanılır. response dosyasının yerine belirtmek için @ karakteri kullanılır. Örnek bir derleme biçimi aşağıdaki gibidir.
csc @response_dosyası /out:Program.exe kaynakdosya.cs
Derleyici Parametrelerine Toplu Bakış
Aşağıdaki listede csc derleyicisi ile kullanılabilecek bütün parametrelerin kullanımı ve açıklaması verilmiştir.
| Parametre | Kullanımı |
| /doc:dosya_ismi | Kaynak dosyasındaki XML yorumlarını ayrıştırarak farklı bir dosyaya kaydetmek için kullanılan bir parametredir. Hatırlayacağınız üzere C# ile yazılmış kaynak kodda /// karakterlerinden sonra XML formatında yorum yazılabilmektedir. |
| /nooutput | Kaynak kodun derlenmesini sağlar ancak herhangi bir çalıştırılabilir dosya oluşturmaz. Bu parametre daha çok kaynak kodda hata ayıklama için kullanılmaktadır. |
| /optimize /optimize+ /optimize- |
Derleme işlemi sırasında kaynak kodda herhangi bir optimizasyonun yapılıp yapılmayacağını belirten bir parametredir. optimize ile optimize+ parametresi eşdeğerdedir. |
| /addmodule:modül_dosyası | Daha önce /module parametresi ile oluşturulan modüllerin herhangi bir çalıştırılabilir dosyaya eklenmesi amacıyla kullanılır. Birden fazla modül dosyasını eklemek için ; karakteri ile modül dosyalarını ayırmak gerekir. |
| /nostdlib /nostdlib+ /nostdlib- |
.NET’in standart kütüphanesi olan System.dll’in otomatik olarak derlenecek koda eklenip eklenmemesini belirten parametredir. Eğer System.dll’i kendi kaynak dosyamızda kullanmayacaksak burdaki sınıfları kendimiz oluşturmalıyız. Çook nadir kullanılabilecek bir parametredir. /nostdlib ile /nostdlib+ parametresi eşdeğerdedir. |
| /reference:assembly_adi
yada /r:assembly_adi |
Başka bir assembly dosyasına ait mata verilere referans vermek için kullanılan parametredir. Assembly’nin bulunduğu yer göreceli adres olabileceği gibi tam adres de olabilir. Eğer birden fazla referans dosyası belirtilecekse ; karakteri ile ayrılmalıdır. |
| /define:SEMBOL /d:SEMBOL |
Derleme zamanında önişlemci sembolü oluşturmak için kullanılır. Kaynak kod içerisinden yapılan #define ön işlemci komutuna karşılık gelmektedir. |
| /warn:<0,1,2,3,4> /w:<0,1,2,3,4> |
Derleme işlemi sırasında verilecek uyarıların derecesini belirlemek için kullanılan parametredir. Eğer bütün uyarıların gösterilmesini istiyorsak /warn:4 şeklinde kullanmalıyız. /warn:0 parametresi ise hiçbir uyarının görüntülenmemesini sağlar. 0 ile 4 arasındaki değerler ise farklı tipteki uyarıların gösterilip gösterilmemesini sağlar. |
| /warnaserror /warnaserror+ /warnaserror- |
Derleme sırasındaki uyarıların hata gibi işlenmesini sağlar. Bu genellikle idealist programcıların kullandığı bir parametredir. Eğer uyarı verecek bir durum varsa kodun derlenmemesi sağlanır. /warnaserror ile /warnaserror+ eşdeğerdedir. |
| /nowarn:uyarı_numarası | Belirtilen numaralı uyarının derleme sırasında verilmemesi için bu parametre kullanılır. Eğer birden fazla uyarının verilmemesini istiyorsak uyarı numaralarını ; karakteril ile ayırmamız gerekmektedir. |
| /fullpaths | Derleme sonrasında eğer herhangi bir dosyada hata var ise hatanın oluştuğu dosyanın tam adresinin hata ile belirtilmesini sağlayan parametredir. |
| /debug /debug+ /debug- |
Hata ayıklamada kullanılacak dosyaların oluşturulması için kullanılan pjarametredir. Eğer debugging işlemini aktif hale getirmek istiyorsak bu parametreyi kullanmamız gerekir. /debug ve /debug+ parametreleri eşdeğerdedir. Hata ayıklama işlemi varsayılan olarak aktif durumda değildir. /debug parametresinin ayrıca full ve pdbonly şeklinde iki seçeneği vardır. Eğer full seçeceği /debug:full şeklinde yazılırsa hata ayıklacı programı çalıştırılan program ile ilişkilendirilir. |
| /checked /checked+ /checked- |
Aritmetik taşma işlemlerinde istisnai bir durumun oluşup oluşmayacağını bildiren parametredir. Varsayılan olarak bu aktif durumda değildir. Kaynak kod içerisinde bu işlemi checked anahtar sözcüklerini kullanarakta yapabiliriz. Eğer taşam oldugunda istisnai durumun oluşmasını istiyorsak /checked yada /checked+ parametresini kullanmalıyız. |
| /bugreport:dosya_adi | Derleme sırasında kaynak kodda oluşabilecek problemlerin ve bu problemlerin önerilen çözümlerinin belirtilen dosyaya yazdırılmasını sağlayan parametredir. Bu parametre ilebelirtilen dosyaya çeşitli derleme çıktılarıda eklenir. |
| /unsafe | Kaynak kodda unsafe anatar sözcüğünün kullanımını geçerli kılınmasını sağlayacak parametredir. Göstericileri kullanmak için unsafe anahtar sözcüğünü kullanmamız gerektiğini hatırlayın. |
| /recurse:dir /recurse:file |
Derleme işlemine katılacak kaynak kodların alt klasörlerde aranmasını sağlayacak parametrelerdir. dir seçeneği ile aramaya başlanacak klasör belirtilir. Bu seçenek ile belirtilen klasör projenin varsayılan çalışma kalsörüdür. Eğer file seçeneği kullanılırsa bu durumda belirtilen dosya için arama yapılacaktır. Bu seçenekte wildcard dediğimiz * karakteri kullanılabilmektedir. |
| /main:sınıf_adi | Eğer kaynak kod dosyamızda birden fazla Main() metodu var ise programımızın hangi sınıftaki Main dosyasından başlayacağını belirten parametredir. Bu da kaynak kodumuzda birden fazla Main metodunun bulunabileceğinin göstergesidir. |
| /nologo | Derleme sonrasında ekranda gösterilen derleyici bilgilerinin kullanıcıya gösterilmemesini sağlayan parametredir. Kanımca çok faydalı olmayan bir parametredir. |
| /help
yada /? |
Derleyici parametreleri ile ilgili yardım bilgilerinin görüntülenmesini sağlayan parametrelerdir. |
| /incremental /incremental+ /incremental- yada /incr |
Derleme işleminin optimize edilmiş biçimde meydana gelmesini sağlayan parametrelerdir. Şöyleki, bir önceki derleme bilgileri .dbg ve .pdb dosylarında tutularak yeni derleme işlemlerinde sadece değiştirilen metotların yeninden derlenmesi sağlanır. Farklı iki derleme işlemi arasındaki farklar ise .incr dosyasında saklanır. Varsayılan olarak bu parametre aktif durumda değildir. /incremental ile /incremental+ parametreleri eşdeğerdedir. |
| /codepage:id_no | Derleme işlemlerine katılacak kaynak kod dosyaları için bir karakter kodlaması numarası alan parametredir. Bu parametre daha çok kaynak kod dosyalarındaki karakterlerin sizin sisteminizde bulunmayan karakter kodlamasına denk düştüğü durumlarda kullanılır. |
| /baseaddress:adres | Yüklenecek DLL lerin belirlenecek bir adresten itibaren belleğe yüklenmesini sağlar. adres değeri 8,10 yada 16 lık sayı düzeninde olabilir. |
| @dosya_adi | Bazı derleyici parametrelerini otomatik olarak derleyiciye bildirmek için bu parametrelerin önceden yazıldığı dosyayı bildirmek için kullanılan parametredir. |
| /linkresource:dosya_adi
/linkres:dosya_adi |
Belirtilen .NET kaynak(resource) dosyasına bir bağlantı oluşturmak için bu parametreler kullanılabilir. |
| /resource:dosya_adi
/res:dosya_adi |
Belirtilen .NET kaynak(resource) dosyasını çıktı dosyasına gömmek için kullanılan parametredir. Birden fazla kaynak dosyası gömülecekse ; karakteri ile ayırmak gerekir. |
| /win32icon:dosya_adi | Belirtilen Win32 ikon dosyasını çıktı dosyasına eklemek için kullanılan parametredir. |
| /win32res:dosya_adi | Belirtilen Win32 kaynak(resource) dosyasını(.res) çıktı dosyasına eklemek için kullanılan parametredir. |
Bu yazıda C# komut derleyicisinin paramtrelerini ve kullanımlarını inceledik. Yukarıdaki tablonun sizin için iyi bir referans kaynağı olacağını umuyorum.
Boxing(Kutulamak) ve Unboxing(Kutuyu Kaldırmak)
Bugünkü makalemizde, Boxing ve Unboxing kavramlarını incelemeye çalışacağız. Boxing, değer türünden bir değişkeni referans türünden bir nesneye aktarmaktır. Unboxing işlemi ise bunun tam tersidir. Yani referans türü değişkenin işaret ettiği değeri tekrar , değer türü bir değişkene aktarmaktır. Bu tanımlarda karşımıza çıkan ve bilmemiz gereken en önemli noktalar, değer türü değişkenler ile referans türü nesnelerin bellekte tutuluş şekilleridir.
.Net ortamında iki tür veri tipi vardır. Referans tipleri (reference type) ve değer tipleri (value type). İki veri türünün bellekte farklı şekillerde tutulmaları nedeni ile boxing ve unboxing işlemleri gündeme gelmiştir. Bu nedenle öncelikle bu iki farklı veri tipinin bellekte tutuluş şekillerini iyice anlamamız gerekmektedir.
Bu anlamda karşımıza iki önemli bellek bölgesi çıkar. Yığın (stack) ve öbek(heap). Değer tipi değişkenler, örneğin bir integer değişken vb.. belleğin stack adı verilen kısmında tutulurlar. .Net’te yer alan değer türleri aşağıdaki tabloda yer almaktadır. Bu tiplerin stack bölegesinde nasıl tutulduğuna ilişkin açıklayıcı şekli de aşağıda görebilirsiniz.
|
Value type ( Değer Tipler) |
|
|
bool |
long |
|
byte |
sbyte |
|
char |
short |
|
decimal |
Struct ( Yapılar ) |
|
double |
uint |
|
Enum ( Numaralandırıcılar ) |
ulong |
|
float |
ushort |
|
int |
|
Tablo 1. Değer Tipleri
şekil 1. Değer Tiplerinin Bellekte Tutuluşu
şekildende görüldüğü gibi, Değer Türleri bellekte, Stack dediğimiz bölgede tutulurlar. Şimdi buraya kadar anlaşılmayan bir şey yok. İlginç olan reference( başvuru) tiplerinin bellekte nasıl tutulduğudur. Adındanda anlaşıldığı gibi reference tipleri asıl veriye bir başvuru içerirler. Örneğin sınıflardan türettiğimiz nesneler bu tiplerdendir. Diğer başvuru tipleri ise aşağıdaki tabloda yer almakdadır.
|
Reference Type ( Başvuru Tipleri ) |
|
Class ( sınıflar ) |
|
Interface (arayüzler ) |
|
Delegate ( delegeler ) |
|
Object |
|
String |
Tablo 2. Başvuru Tipleri
Şimdi gelin başvuru türlerinin bellekte nasıl tutulduklarına bakalım.
şekil 2. Başvuru tiplerinin bellekte tutuluşu.
Görüldüğü gibi,başvuru tipleri hakikatende isimlerinin layığını vermekteler. Nitekim asıl veriler öbek’te tutulurken yığında bu verilere bir başvuru yer almaktadır.
İki veri türü arasındaki bir farkta bu verilerle işimiz bittiğinde geri iade ediliş şekilleridir. Değer türleri ile işimiz bittiğinde bunların yığında kapladıkları alanlar otomatik olarak yığına geri verilir. Ancak referans türlerinde sadece yığındaki başvuru sisteme geri veririlir. Verilerin tutulduğu öbekteki alanlar, Garbage Collector’un denetimindedirler ve ne zaman sisteme iade edilicekleri tam olarak bilinmez. Bu ayrı bir konu olmakla beraber oldukça karmaşıktır. İlerleyen makalelerimizde bu konudan da bahsetmeye çalışacağım.
Değer türleri ile başvuru türleri arasındaki bu temel farktan sonra gelelim asıl konumuza. .NET’te her sınıf aslında en üst sınıf olan Object sınıfından türer. Yani her sınıf aslında System.Object sınıfından kalıtım yolu ile otomatik olarak türetilmiş olur. Sorun object gibi referans bir türe, değer tipi bir değerin aktarılmasında yaşanır. .NET’te herşey aslında birer nesne olarak düşünülebilir. Bir değer türünü bir nesneye atamaya çalıştığımızda, değer türünün içerdiği verinin bir kopyasının yığından alınıp, öbeğe taşınması ve nesnenin bu veri kopyasına başvurması gerekmektedir. İşte bu olay kutulama ( boxing ) olarak adlandırılır. Bu durumu minik bir örnek ile inceleyelim.
| using System;
namespace boxunbox obj=db; Console.WriteLine(db.ToString()); |
Kodumuzun çalışmasını inceleyelim. Db isimli double değişkenimiz bir değer tipidir. Örnekte bu değer tipini object tipinden bir nesneye aktarıyoruz. Bu halde bu değerler içerisindeki verileri ekrana yazdırıyoruz. Sonra db değerimizi 1 arttırıyor ve tekrar bu değerlerin içeriğini ekrana yazdırıyoruz. İşte sonuç;
şekil 3 Boxing İşlemi
Görüldüğü gibi db değişkenine yapılan arttırım object türünden obj nesnemize yansımamıştır. Çünkü boxing işlemi sonucu, obj nesnesi , db değerinin öbekteki kopyasına başvurmaktadır. Oysaki artım db değişkeninin yığında yer alan orjinal değeri üzerinde gerçekleşmektedir. Bu işlemi açıklayan şekil aşağıda yer almaktadır.
şekil 4. Boxing İşlemi
Boxing işlemi otomatik olarak yapılan bir işlemdir. Ancak UnBoxing işleminde durum biraz daha değişir. Bu kez , başvuru nesnemizin işaret ettiği veriyi öbekten alıp yığındaki bir değer tipi alanı olarak kopyalanması söz konusudur. İşte burada tip uyuşmazlığı denen bir kavramla karşılaşırız. Öbekten, yığına kopylanacak olan verinin, yığında kendisi için ayrılan yerin aynı tipte olması veya öbekteki tipi içerebilecek tipte olması gerekmektedir. Örneğin yukarıdaki örneğimize unboxing işlemini uygulayalım. Bu kez integer tipte bir değer türüne atama gerçekleştirelim.
| using System;
namespace boxunbox obj=db; Console.WriteLine(db.ToString()); int intDb; } |
Bu kodu çalıştırdığımızda InvalidCastException istisnasının fırlatılacağını görüceksiniz. Çünü referenas tipimizin öbekte başvurduğu veri tipi integer bir değer için fazla büyüktür. Bu noktada (int) ile açıkça dönüşümü bildirmiş olsak dahi bu hatayı alırız.
şekil 5. InvalidCastException İstisnası
Ancak küçük tipi, büyük tipe dönüştürmek gibi bir serbestliğimiz vardır. Örneğin,
| using System;
namespace boxunbox obj=db; Console.WriteLine(db.ToString()); /*int intDb; double dobDb; |
Bu durumda kodumuz sorunsuz çalışacaktır. Çünkü yığında yer alan veri tipi daha büyük boyutlu bir değer türünün içine koyulabilir. İşte buradaki aktarım işlemi unboxing olarak isimlendirilmiştir. Yani boxing işlemi ile kutulanmış bir veri kümesi, öbekten alınıp tekrar yığındaki bir alana konulmuş, dolayısıyla kutudan çıkartılmıştır. Olayın grafiksel açıklaması aşağıdaki gibidir.
şekil 6. Unboxing İşlemi
Geldik bir makalemizin daha sonuna. Bir sonraki makalemizde görüşmek dileğiyle hepinize mutlu günler dilerim
