Alıntı (Alper#):
>
- https://github.com/DerelictOrg/DerelictGLFW3 şu örnekte anladığım kadar Windows için glfw.dll dosyasının methodlarını kullanabiliyoruz.
Evet, D kodları C kütüphanelerini olduğu gibi çağırabilir. Gereken tek şey, D tarafında çağrılmakta olan işlevin bir C işlevi olduğunu (ve ne parametreler aldığını) bildirmektir.
Alıntı:
> Language Bindings dedikleri olayı çok güzel şekilde açıklıyor.
O zaman bu yazacaklarım biraz tekrar olacak.
C ve D gibi derlemeli dillerde kaynak kod makine koduna dönüştürülür. Bu adımdan sonra artık kodun hangi dilden gelmiş olduğu değil, hangi işlemcinin olduğu belirgindir.
İçinde foo(int) ve bar(double) diye iki işlev bulunan bir C kaynak dosyası derlendiğinde c.o dosyası oluşmuş olsun. O dosyanın içinde temelde bağlayıcının (linker veya loader) yararlandığı temelde şu bilgi vardır: "Bu dosyada isimleri (tarihsel nedenlerle) _foo ve _bar olan iki işlev var ve dosya içinde şu noktada bulunuyorlar." O kadar...
C++ ve D gibi dillerde durum bundan farklı olmamakla birlikte, işlev isimlerinde ufak bir güçlük vardır. Bu dillerde işlev yükleme diye bir olanak olduğundan, örneğin foo(int) yanında foo(string) de bulunabilir. Bu yüzden, derlenen dosyadaki sembol isimleri basitçe _foo (ve _foo) olamaz. Bunların .o dosyalardaki işlev isimlerinin aldıkları parametrelerin türlerini de gösterecek biçimde _foo_int ve _foo_string gibi olması gerekir. (Bu isimleri örnek olarak verdim; gerçekte daha farklıdır. İlgilenenler core.demangle'daki mangle işlevine bakabilirler: http://dlang.org/phobos/core_demangle.html#.mangle.)
Yani, bir D programı foo(42) dediğinde bunun _foo_int adlı bir işleve doğru olduğu anlaşılır. Sorun: Eğer çağrılan foo(int) C ile derlenmiş bir program parçasında bulunuyorsa, bağlayıcı çağıranla işlevi bağlayamaz.
Bunun çözümü, D'nin extern(C) olanağından yararlanmaktır. extern(C) olarak bildirilen bir işlevin isminin C kurallarına göre aranır:
extern(C) void foo(int); // Bir C binding'i
void main(){
foo(42); // <-- Bu, extern(C) yüzünden _foo adlı bir işleve çağrıdır
// (Yani, _foo_int adlı bir işleve değil.)
}
İşte, binding'ler, bir C kütüphanesinin işlevlerini (ve türlerini) D'nin kullanabildiği biçimde extern(C) olarak bildiren basit dosyalardır.
Alıntı:
> Anlamadığım nokta C/C++ ile yazılmış binary lib. nasıl iletişim kuruyor.
Yukarıda da dediğim gibi, foo(42) ifadesi şöyle kodlanıyor: "burada _foo isimli işlevi çağırıyoruz." Çağrılmakta olan işlevin hangi program parçasında (.o dosyası) veya kütüphanede olduğunu bulup herşeyi bir araya getirip programı oluşturmak bağlayıcının görevidir.
Yani, burada çağıranla çağrılanın isimlerinin aynı biçimde kurulmuş olmalarından başka bir şey gerekmiyor. (Aslında 42 gibi parametre değerlerinin çağrı yığıtına ne biçimde yerleştirildikleri de önemli ama o bu konuyla doğrudan ilgili değil.)
Alıntı:
> Örneğin:
> alias da_glfwCreateWindow = GLFWwindow* function( int,int,const( char )*,GLFWmonitor*,GLFWwindow* );
> ```
>
> Bu kod bize ne anlatıyor?
O bu konuyla tam ilgili değil. Yukarıdaki satır sağ tarafta bir işlev göstergesi türü tanımlıyor: iki int vs. alan ve GLFWwindow* döndüren işlev göstergesi.
Sol tarafındaki ise ona güzel bir isim veriyor: da_glfwCreateWindow.
Dolayısıyla aşağıdaki kodun anlamı, "foo şöyle şöyle bir işlev göstergesidir":
da_glfwCreateWindow foo;
O bildirime uyan bir işlevimiz varsa, foo'yu ona eşitleyebiliriz ve sonra onu çağırabiliriz:
foo = &benimUygunİşlevim;
foo(42, 43, /* vs */);
Alıntı:
> 2) Language Bindings nasıl yapılıyor. Tam olarak nasıl bir mantık işliyor.
Tekrar etmek pahasına, binding, temelde kütüphanenin .h dosyasındaki bildirimleri vs. bir .d dosyası içinde extern(C) olarak tanımlamaktan başka bir şey değil.
Alıntı:
> OpenGL C ile yazılmış grafik kütüphanesini başka dillerle nasıl hükmediliyor.
Yine tekrar etmek pahasına, kütüphanenin hangi dilde yazıldığının hiçbir önemi yok. Kütüphanede _foo diye bir işlev varsa, onu çağıran kod o kütüphaneyle bağlanabilir.
Alıntı:
> Aklımda daha çok soru var ama en önemlisi bunlar.
Bunlar "cevabını bulamadığım sorular"dan daha uygun ;) konu başlıklarını hakeden çok ilginç sorular. Ben her soru için ayrı konu açmayı seviyorum. O zaman konular daha derli toplu oluyor.
Ali
--
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]