ANSI Standartları,
uygulamalarda sıklıkla kullanılan fonksiyonları, tipleri, makroları vb içeren
bir kütüphane tanımlamıştır. Örneğin uygulamalarımızda giriş çıkış işlemleri
için kullandığımız printf ve scanf fonksiyonları bu kütüphane içerisinde yer
alırlar. Bu kütüphane ’Standart Kütüphane’ olarak bilinir. C derleyicileri zorunlu
olarak, bu kütüphaneyi kullanma imkanı sağlarlar. Standart kütüphane içerisindeki
fonksiyonlar, ’Standart C Fonksiyonları’ olarak bilinir. Bu fonksiyonlar, konularına
göre gruplanarak standart başlık dosyaları oluşturulmuştur. printf ve scanf
fonksiyonlarını çağırdığımız uygulamalarda, kaynak kod dosyamıza ’stdio.h’ standart
başlık dosyasını ekleriz. Çünkü bu fonksiyonlara ilişkin prototip bildirimleri
bu başlık dosyasında yer almaktadır. ANSI Standartları, standart kütüphaneyi,
programların taşınabilirliğini artırmak amacıyla oluşturmuşlardır. Standart
kütüphaneyi genel hatlarıyla bilmek uygulamalarda işimizi kolaylaştıracaktır.
Bu yazımızda da kütüphaneyi genel hatlarıyla tanımaya çalışacağız.
Standart kütüphane
içerisinde yer alan bu fonksiyonlar haricinde, derleyiciler uygulamalarda gerekli
olabilecek birtakım fonksiyonları içeren kendi kütüphanelerini de oluşturmuşlardır.
Bu kütüphaneler standart değildir. Yani tüm derleyiciler bu kütüphaneleri kullanma
imkanı sağlamayabilir. Bu gibi kütüphanelerde yer alan fonksiyonların kullanılması,
kodumuzun taşınabilirliğini azaltır. Kodumuzu yazarken kullandığımız derleyici
haricindeki herhangi bir derleyicide derleme işlemi başarısızlıkla sonuçlanabilir.
Kütüphane
Kavramı
Öncelikle ’kütüphane’
kavramını ele alalım. Yazacağımız bazı fonksiyonlar, makrolar ya da tipler,
birden fazla uygulamada bize gerekli olabilir. Örneğin verilen sayıların ortalamasını
alarak bu değeri geri döndüren bir fonksiyon yazdığımızı düşünelim. Böyle bir
fonksiyon bize birbirinden bağımsız birkaç uygulamada gerekli olabilir. Bu durumda
bu fonksiyona ihtiyacımız olan her uygulamada, aynı kodu yeniden yazmak yerine
bir kütüphane oluşturarak bu fonksiyonu oluşturduğumuz bu kütüphaneye yerleştiririz
ve gereksinim duyduğumuz tüm uygulamalarda kullanabiliriz.
Kütüphaneler, derlenmiş
dosyalardır. Kütüphane oluştururken, projemize c uzantili bir kaynak kod dosyası
ve h uzantılı bir başlık dosyası ekleriz. Kaynak kod dosyasında, kütüphanemize
ekleyeceğimiz fonksiyonların tanımlamaları yapılır. Başlık dosyasında ise bu
fonksiyonlara ilişkin prototip bildirimleri yapılır. Başlı kdosyaları aynı zamanda
makro bildirimlerini, tip bildirimlerini vb içerebilir. Kütüphane projemizi
derlediğimizde, kütüphanemizin içerisindeki tüm tanımlamalar, obj modülü içerisine
yazılır. ’obj’ uzantılı dosyalar, derleyicilerin çıktı dosyalarıdır.
Kütüphane kavramı,
statik ve dinamik kütüphane olmak üzere iki başlık altında ele alınır. Windows
sistemlerinde statik kütüphanelerin uzantıları ’.lib’,, dinamik kütüphanelerin
uzantıları ise ’.dll’ şeklindedir. Statik kütüphaneler kullanıldığında, bağlayıcı
bağlama aşamasında statik kütüphane içerisindeki fonksiyonları kütüphaneden
çekerek ’.exe’ uzantılı dosyaya yazar. Dinamik kütüphaneler kullanıldığında
ise, kodun hangi yerinden hangi fonksiyonun çağrıldığı bilgisini yazar ve çalışma
zamanı içerisinde fonksiyonu alır. Derleme aşamasında, kütüphaneden çağrılacak
fonksiyonların (veya makroların, tiplerin) prototip bildirimlerine ihtiyacımız
olduğu için kütüphanelere ilşkin başlık dosyalarını kaynak kodumuzun başına
eklememiz gereklidir. Ayrıca bağlama aşamasında veya çalışma zamanında gerekli
olacak kütüphane dosyalarını da (.lib ya da .dll uzantılı dosyalar) projemize
eklememiz gereklidir.
Kütüphane
Projeleri Nasıl Oluşturulur ?
Microsoft Visual
C++ 6.0 programını kullanarak bir statik kütüphane projesinin ve bir dinamik
kütüphane projesinin nasıl oluşturulacağını inceleyelim. Derleyici IDE’leri
kütüphanelerin oluşturulması için ’Yeni Proje’ seçeneği altında özel seçenekler
içerirler. Microsoft Visual C++ 6.0 IDE’sini açarak ’Dosya’ (File) menüsü altında
’Yeni’ (New) seçeneğini seçelim. Açılan pencerede, ’Projeler’ (Projects) sekmesine
geçelim :
Listenin sağ sütununda
yer alan ’Win32 Dynamic-Link Library’ ve ’Win32 Static Library’ seçenekleri
kütüphane projeleri oluşturmamızı sağlar. Buradan statik veya dinamik kütüphane
seçeneklerinden birisi seçildikten sonra oluşturulan proje derlendiği zaman
artık ’.exe’ uzantılı çalıştırılabilir bir dosya değil, seçilen seçeneğe göre
’.lib’ veya ’.dll’ uzantılı kütüphane dosyaları elde edilir. İstediğimiz tanımlamaları
yaptıktan sonra elde ettiğimiz kütüphane dosyalarını kullanmak istediğimizde
ise, istemci projede bu kütüphane dosyalarını kullandığımızı belirtmemiz gereklidir.
Bu belirleme, oluşturduğumuz istemci projenin ayarlarında yapılır. İstemci projemiz
açıkken ’Proje’ (Project) menüsünden ’Ayarlar’ (Settings) seçeneği seçilerek
ayarlamaların yapıldığı pencereye erişilir :
Yukarıdaki ayarlar
penceresi, chLib.lib isimli kütüphane dosyasını kullanan bir Windows uygulamasına
aittir. Bu uygulama, daha önceden oluşturularak derlenmiş chLib isimli bir kütüphane
içerisindeki fonksiyonları kullanmaktadır. Fonksiyonlara ilişkin prototip bildirimlerinin
yer aldığı başlık dosyası, uygulamanın ilgili kaynak kod dosyasında, ’#include’
önişlemci komutu ile eklenmiştir. Bağlama aşamasında gerekli olan ’.lib’ uzantılı
kütüphane dosyası da, projeye yukarıdaki pencere aracılığıyla eklenir. Bu pencerede,
’Bağlama’ (Link) sekmesine geçildiğinde, ’Amaç / kütüphane modülleri’ (Object
/ library modules) isimli bir kısım görülmektedir. Burada, proje içerisinde
kullanılan kütüphane dosyaları belirtilir. Biz de uygulama içerisinde kullandığımız
chLib.lib isimli kütüphane dosyamızı bu kısımda belirttik.
Ticari bir kütüphane
hazırladığımızı düşünürsek, kütüphanemizi satın alacak kişilerin kodlarımızı
görmesini istemeyebiliriz. Bu durumda yapmamız gereken kütüphanemizin .lib veya
.dll dosyasını istemciye vermek olacaktır. Ayrıca bununla beraber, kütüphanemizin
içeriğine dair bilgiler içeren başlık dosyasını da istemciye vermeliyiz. İstemci
kişi, başlık dosyasına bakarak, kütüphane içerisinde yer alan fonksiyonlar hakkında
bilgi edinebilir, kaynak kod dosyasına bu başlık dosyalarını ve projesine de
kütüphane dosyasını ekleyerek kendi projelerini bizim kütüphane fonksiyonlarımızı
kullanarak oluşturabilir.
Örnek
Uygulama
Şimdi bir kütüphane
oluşturarak uygulama yapalım. Bu uygulamayı örnek teşkil etmesi amacıyla yapacağımız
için kütüphaneye çok basit bir fonksiyon ekleyeceğiz. Sonra yine basit bir konsol
uygulaması oluşturarak bu kütüphane fonksiyonumuzu çağıracağız.
Yeni Proje penceresinde
statik kütüphane seçeneğini seçerek kütüphane projemizi oluşturalım. Kütüphanemizin
kaynak kod dosyasının ve başlık dosyasının içeriği şöyle :
//StcLib isimli
Statik Kütüphane Projesi :
//StcLib.h - Statik Kütüphane Projesi Başlık Dosyası
#ifndef _STCLIB_H_
#define _STCLIB_H_
void StaticLibraryFunction();
#endif
//-----------------------------------------------------
//StcLib.c - Statik Kütüphane Projesi Kaynak Kod Dosyası
#include
"StcLib.h"
#include <stdio.h>
void StaticLibraryFunction()
{
    printf("Statik kütüphane fonksiyonu çağrıldı...\n");
}
|
Projeyi derlediğimizde,
’Debug’ dizininde ’StcLib.lib’ isimli kütüphane dosyası oluşturulacaktır. Şimdi
bir konsol uygulaması oluşturalım. Konsol uygulamasının dizini içerisinde ’StcLib.h’
isimli başlık dosyasını kopyalamalıyız. Bu kütüphane fonksiyonunu çağırmak için
prototip bildirimine ihtiyacımız vardır. Kopyalama işleminden sonra, konsol
uygulamamızı şu şekilde oluşturalım :
//LibraryTest
isimli Konsol Uygulaması
#include "StcLib.h"
int
main()
{
    StaticLibraryFunction();
    DynamicLibraryFunction();
    return 0;
}
|
Bu aşamaya gelinceye
kadar konsol projemizin ayarlarına hiç dokunmadık. Şimdi uygulamamızı derleyelim.
Derleme sonucunda hiçbir hata almadığımızı göreceksiniz :
Derleyici, çağrılan
fonksiyonun prototip bildirimini, projenin bulunduğu dizindeki başlık dosyasında
görebildiği için hatasız bir şekilde derleme işlemini bitirir. Ancak bağlama
aşamasında sorun çıkacaktır. Prototip bildirimi görülen bu fonksiyonun tanımlaması
nerededir? Henüz konsol projemize bunu bildirmedik. Bağlama işlemi sırasında
alacağımız hata şöyle olacaktır :
Bağlayıcı (linker),
main ana fonksiyonu içerisinde çağrılan kütüphane fonksiyonunun tanımlamasını
bulamamıştır. Bu hatayı gidermek için proje ayarları penceresine gelerek bu
fonksiyonu içeren kütüphaneyi kullandığımızı belirtmemiz gerekmektedir. Öncelikle
statik kütüphe dosyamızı, yani StdLib.lib isimli dosyasımızı, projenin bulunduğu
dizine ya da bağlayıcının kütüphane dosyaları için baktığı dizine kopyalamamız
gerekmektedir. Microsoft Visual C++ 6.0 programı için bu dizin ’Program Files\Microsoft
Visual Studio\VC98\Lib’ dizinidir. Kütüphane dosyasını bu dizine ya da projenin
dizinine kopyaladıktan sonra uygulama projemizin ayarlar penceresinde kütüphane
dosyamızın adını belirtiriz :
Kütüphane dosyasını
kopyaladığımızdan emin olduktan sonra derleme ve bağlama işlemleri hatasız bir
şekilde sonuçlanacaktır. Uygulamayı çalıştırarak kütüphane fonksiyonunun çağrıldığını
test edebilirsiniz.
Standart kütüphaneye
geri dönersek, öncelikle standart başlık dosyalarının bir listesini görelim
:
assert.h
|
float.h
|
math.h
|
stdarg.h
|
stdlib.h
|
ctype.h
|
limits.h
|
setjmp.h
|
stddef.h
|
string.h
|
errno.h
|
locale.h
|
signal.h
|
stdio.h
|
time.h
|
Standart fonksiyonlar,
çeşitli kriterlere göre gruplandırılmış ve bunlara ilişkin prototip bildirimleri
belli başlık dosyaları içerisinde belirtilmiştir. assert.h başlık dosyalarında,
programlarda oluşacak hataları kontrol altına almak için kullanılan assert isimli
makro yer alır. Nesne yönelimli programlama dillerinde istisna yakalama (exception
handling) olarak bilinen işleme benzer olarak, C dilinde bu makro hata yönetimini
sağlar. ctype.h başlık dosyasında karakterler üzerinde işlemler yapan fonksiyonlar
yer alır. errno.h başlık dosyası içerisinde hata numaraları ve hata numarası
aralıklarını belirten sabitler ve bazı makrolar vardır. float.h başlık dosyası
içerisinde, kayan-noktalı sayılarla (float sayılar) ilgili sabitler, limits.h
başlık dosyası içerisinde ise tamsayılarla ilgili sabitler vardır. locale.h,
yerelleştirme ile ilgili birtakım işlemler yapan fonksiyonları ve tipleri içerir.
math.h başlık dosyasında matematiksel işlemler yapan fonksiyonlar ve makrolar
vardır. setjmp.h içerisindeki makrolar, içiçe çağrılan fonksiyonlardan tek bir
adımda çıkabilmeyi sağlarlar. signal.h başlık dosyasında, çalışma anında oluşabilecek
birtakım istisnai durumların kontrol edilmesi amacıyla kullanılan fonksiyonlar
yer alır. stdarg.h başlık dosyasında, değişken argüman listesine sahip olan
fonksiyonlar oluşturabilmek için kullanılan makrolar vardır. stddef.h başlık
dosyası, ortak sabitler, türler ve değişkenler için tanımlar ve bildirimler
içerir. stdio.h başlık dosyası, temel giriş çıkış işlemleri için kullanılan
fonksiyonları içerir. stdlib.h başlık dosyası, dinamik tahsisat yapan fonksiyonlar,
sayı dönüşümü fonksiyonları gibi yararlı işlemler yapan birtakım fonksiyonları
içerir. string.h başlık dosyası, karakter katarları üzerinde işlemler yapan
fonksiyonları içerir. time.h başlık dosyası tarih ve zaman ile ilgili işlemler
yapan fonksiyonları içerir.
Bu yazımızda, kütüphane
kavramının ne olduğuna, statik bir kütüphanenin nasıl oluşturulacağına, statik
bir kütüphane fonksiyonunun bir uygulama içerisinden nasıl çağrılacağına ve
standart başlık dosyalarına değindik. Önümüzdeki yazılarda, standart fonksiyonların
işlevlerine değineceğiz. Yaptığımız statik kütüphane uygulamasını buradan indirebilirsiniz.
Yeni bir yazıda
görüşmek üzere mutlu günler dilerim.
KAYNAKLAR
- The C Programming
Language, B. Kernighan, D. Ritchie
Makale:
Kütüphane Kavramı ve Standart Kütüphane C ve Sistem Programlama Çiğdem Çavdaroğlu
|