15 Ağustos 2017 Salı

Main metodu

Not :  Konu ile ilgili Komut Satırı Parse Etme başlıklı yazıya göz atabilirsiniz.

Windows GUI
Windows GUI uygulamaları WinMain ile başlarlar


Main metodu
Hangi programlama dili olursa (C, C++, Java) derlediğimiz program çalışmaya başlamadan önce - yani main metodumuzdan önce - kullandığımız dile ait runtime kütüphanesi bazı hazırlıklar yapar.

Örneğin Windows üzerindeki C runtime kütüphanesi _mainCRTStartup gibi fonksiyonları çağırır. Böylece main metodumuz uygulamamıza geçilen argümanlar parse edilmiş olarak başlayabilir. Açıklaması şöyle
The Visual Studio linker looks for int mainCRTStartup(void); and uses that, unless you specify another entry point with /ENTRY. The default implementation of mainCRTStartup calls GetCommandLine() to fill in argv[] before calling main(argc,argv). There are also other things in mainCRTStartup which you might want to happen: run global ctors, initialize the CRT state, ...

Dönen Metod Değeri
posix
main dönebilir. int'in değeri POSIX platformlarında 8 bit büyüklüğündedir. Yani 0-255 arasıdır.
Şöyle bir program olsun.
int main()
{
    return -1;
}
Linux'ta bunu çalıştırırsak
echo $?
Çıktı olarak şunu görürüz.
255
windows
Windows'ta 32 bit sayılar döndürülebiliyor. 64 bit sayı dönmüyor ancak zaten lazım da değil.

C++
Main Metodu yazısına taşıdım.

Parametreler
Parametreler Address Space Layout Randomization ile bellekte rastgele bir yere yerleştirilir. Açıklaması şöyle
When the kernel executes a process, it copies the command line arguments to read-write memory belonging to the process (on the stack, at least on Linux). The process can write to that memory like any other memory. When ps displays the argument, it reads back whatever is stored at that particular address in the process's memory. Most programs keep the original arguments, but it's possible to change them.
Bu parametreler değişitirilebilir. ps metodunun açıklaması şöyle
It is unspecified whether the string represented is a version of the argument list as it was passed to the command when it started, or is a version of the arguments as they may have been modified by the application. Applications cannot depend on being able to modify their argument list and having that modification be reflected in the output of ps.
Parametreleri değiştirmek için şöyle yaparız.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
  int i;
  
  for (i = 0; i < argc; i++)
  {
    memset(argv[i], '0' + (i % 10), strlen(argv[i]));
  }
  return 0;
}
Eğer main metodu parametre alıyorsa sonuncu parametreden sonraki şey NULL olmalıdır. Bu NULL olma kuralı ilk K&R 1978 kitabında yok daha sonradan eklenmiş.
argv[argc] is required to be a null pointer
Ne kadar büyüklükte argv girilebileceği ise işletim sistemi ayarlarından var. Eğer kısıtı aşarsak
"Argument list too long" şeklinde bir hata alırız.

Main'in Döndürdüğü Parametre
Main int döner. int[] dönemez. Standart döndürülebilen parametre değeri olarak sadece EXIT_SUCCESS (0) ve EXIT_FAILURE (1) değerlerini tanımlar.

Main'den Önce Çağrılabilecek Metodlar
GNU Runtime - Main'den Önce Çağrılabilecek Metodlar yazısına taşıdım.

Main ve .so Dosyası
Bir .so dosyasına main metodu eklenebiliyor. Böylece .so dosyası çalıştırılıp versiyon bilgisi ekrana bastırılabiliyor. Örneğin şu komut çalıştırılabiliyor.
$ /lib/x86_64-linux-gnu/libc.so.6
Derlerken sanırım -pie seçeneğini kullanmak gerekiyor

Main'den Main Çağırma
İnanması ve düşünmesi güç ama C'de bu yapılabiliyor. Örnekte stdin'den okunan veriyi stdout'a tersine yazan program var ve main'den main'i çağırarak yapıyor.
main(c){if(c=getchar(),c>=0)main(),putchar(c);}

Aynı şeyi Java'da da yapmak mümkün. Örnekte exception yiyen bir program tekrar başlatılıyor.
public static void main(String[] args) {
    try {
        //something wrong happens here
    }catch(Throwable e) {
        e.printStackTrace();
        main(args);
    }
}
Java
Main Metodu yazısına taşıdım.
C#
main metodu void veya int dönebilir.

.Net
.Net assemblylerinin entry metodu EntryPoint ile alınabilir.


Hiç yorum yok:

Yorum Gönder