Forum: D Programlama Dili RSS
Manual Olarak Link Etmek
Avatar
zekeriyadurmus #1
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Manual Olarak Link Etmek
dmd'nin linkleme işlemini iptal edebiliyoruz ve manual olarak link edebilme imkanımız var ama bu nasıl olacak bununla ilgili bir kaynak var mı?

Bunu yapmak istememin sebebi C, C++ gibi dilleri de D ile beraber derleyebilmek.

Ayrıca http://www.linuxjournal.com/content/add-auto-incrementing-… adresindeki olay çok dikkatimi çekti.

Zekeriya
Bilgi meraktan gelir...
Bu mesaj zekeriyadurmus tarafından değiştirildi; zaman: 2014-02-08, 11:53.
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Sen bunu istemiyorsun ama C ile oluşturulmuş program parçası ile D programı oluşturmayı göstereceğim. Şöyle bir C dosyası olsun:

int C_islevi(int i)
{
    return i * 7;
}

Onu bağlamadan yalnızca derleyelim:

$ gcc -c deneme.c -o deneme_c.o

Şöyle de bir D dosyası olsun:

extern(C) int C_islevi(int i);
 
void D_islevi()
{
    assert(C_islevi(6) == 42);
}
 
void main()
{
    D_islevi();
}

İkisini kullanarak ve bağlayarak bir program şöyle oluşturulabilir:

dmd deneme_c.o deneme.d -ofdeneme

Şimdi tersini deneyeceğim: Programı gcc ile oluşturacağım ve hatta C'den D'yi çağırmaya çalışacağım. Önce D dosyasından main'i kaldırıyorum ve C tarafından çağrılacak olan işlevini extern(C) olarak bildiriyorum. Bu işlev de tekrar C'ye dönüp az önce yazdığımız C_islevi'ni çağıracak:

extern(C) int C_islevi(int i);
 
extern(C) void D_islevi()
{
    assert(C_islevi(6) == 42);
}

Onu dmd ile bağlamadan yalnızca derliyorum:

$ dmd deneme.d -c -ofdeneme_d.o

Şimdi bir tane de C main dosyası yazalım. Bu dosya hem D tarafındaki işlevi bildirecek hem de onu çağıracak:

// main.c
 
void D_islevi();    // Bildirim
 
int main()
{
    D_islevi();
}

Şimdi az önce oluşturduğumuz deneme_c.o ve deneme_d.o'yu da kullanarak bu main.c ile bir program oluşturmaya çalışıyorum:

$ gcc deneme_c.o deneme_d.o main.c -odeneme

Demek ki eksik tanımlar var:

deneme_d.o: In function `_D6deneme8__assertFiZv':
deneme.d:(.text._D6deneme8__assertFiZv+0x16): undefined reference to `_d_assertm'
deneme_d.o:(.text.d_dso_init[.data.d_dso_rec]+0x32): undefined reference to `_d_dso_registry'
/tmp/ccX1mdfa.o: In function `main':
main.c:(.text+0xa): undefined reference to `D_islevi'
collect2: ld returned 1 exit status


Hmmm. Olmadı. libphobos'u eklemeyi deniyorum ama libcurl-gnutls.so.4 eksik görünüyor:

$ gcc deneme_c.o deneme_d.o main.c -lphobos2 -odeneme
/usr/bin/ld: warning: libcurl-gnutls.so.4, needed by /usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../lib64/libphobos2.so, not found (try using -rpath or -rpath-link)
...

libcurl-gnutls.so.4'in neden gerektiğini anlamıyorum ve şimdilik bu işi bırakıyorum. :-/

Ali
Avatar
zekeriyadurmus #3
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ali Hocam harikasınız :) Derleyiciye direk obj dosyası gönderildiğini bilmiyordum.

C tarafında aynı işlemi yapılamamasının sebebi druntime'ın derlemeye dahil olmaması. Buradaki _d_assertm hatalarını yeniden tanımlayarak geçebiliriz (os işi ile uğraşırken öyle yapmıştık :) ) yeniden tanımlamadan da kastım boş bir extern(C) kaydı. Github üzerinde arama yapınca https://github.com/D-Programming-Language/druntime/blob/9a… şurada buldum _d_dso_registry ın tanımlandığı yeri.

Şimdi deneyeceğim druntime ı dahil etmeyi eğer başarabilirsem yazarım buraya.

Çok teşekkür ederim :)

Zekeriya
Bilgi meraktan gelir...
Avatar
zekeriyadurmus #4
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ali hocam -lphobos2 li olan kod bende çalıştı :) Teşekkür ederim. Lakin o fonksiyon içerisinde writeln yaptım ve konsola hiçbirşey yazdırmadı acaba neden olabilir?

Ek: Dmd ile derlemeyi unutmuşum şimdi segmentation fault veriyor. Onun haricinde assert verdirdiğimde de aynı hatayı veriyor. Sanırsam D main'e girmeden önce sisteminde bazı şeyleri tanımlıyor o yüzden de C üzerinde bir çok D olanağı aktif olamıyor.
Try catch ile deneyeceğim ne çıktısı verecek bakalım.

Zekeriya
Bilgi meraktan gelir...
Bu mesaj zekeriyadurmus tarafından değiştirildi; zaman: 2014-02-09, 01:51.
Avatar
zekeriyadurmus #5
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Neyse çokta önemli değil doğrusu C ye D yi dahil edince bu tarz hatalar vermesi benim için önemli olan C yi D'ye dahil edince sorun çıkmaması ki çıkmıyorda. Ayrca hocam buradaki olayı bloguma da yazdım.

http://www.talhadurmus.com/c-dilini-d-ile-birlikte-derlemek/

ve ayrıca http://www.tiobe.com/index.php/content/paperinfo/tpci/inde… burada d dili 18.sıraya yerleşmiş :) D için büyük bir ilerleme aslında Salih hocam da bir blog açsa birkaç tane daha böyle web siteleri D dili hakkında belki kullanımını daha da yaygınlaştırabiliriz.

Zekeriya
Bilgi meraktan gelir...
acehreli (Moderatör) #6
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Ben de D çalışma ortamının Runtime.initialize() diye hazırlanması gerektiğini öğrendim ama hiç denemedim.

Ali
Avatar
zekeriyadurmus #7
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ali hocam az önce test ettim

import std.c.stdio;;
import std.stdio;
import core.runtime;
 
extern(C) void C_fonksiyonu();
 
extern(C) int D_fonksiyonu(int val){
  Runtime.initialize();
  C_fonksiyonu();
  try{
      assert(0);
  }catch(Throwable x){
      writeln(x.msg);
  }
 
  printf("D_fonksiyonu çağırıldı\n");
  return val;
}

Gayet iyi çalışıyor :)

Aldığım çıktı:

zack@drzack:~/Desktop/d in c$ make
C_fonksiyonu çağırıldı
Assertion failure
D_fonksiyonu çağırıldı
1000
zack@drzack:~/Desktop/d in c$

Zekeriya
Bilgi meraktan gelir...
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Çok sevindim. :) Herhalde söylemeye gerek yok ama Runtime.initialize()'ın tek kere çağrılması yeterli (ve belki de öyle olması gereklidir). O yüzden D_fonksiyonu()'ndan başka bir yerde çağrılmalı.

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-19, 04:28:44 (UTC -08:00)