Forum: D Programlama Dili RSS
D ile C kütüphaneleri nasıl kullanılıyor?
acehreli (Moderatör) #1
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ı
Konu adı: D ile C kütüphaneleri nasıl kullanılıyor?
Tanıtım sayfalarında C kütüphane fonksiyonlarının oldukları gibi çağrılabildiklerini okuyorum ama nasıl yapıldığını bilmiyorum.

Örneğin klavyeden basılan tuşları ncurses ile algılayan şu C programını D'de nasıl yazarız? Yani aynı ncurses kütüphanesini nasıl kullanırız?

#include <ncurses.h>
 
int main()
{
    char c = '\0';
 
    // Bastan bunu cagirmak sartmis
    initscr();
 
    // Bunlarin cagrilmasi oneriliyor
    cbreak();
    noecho();
    nonl();
    intrflush(stdscr, FALSE);
    keypad(stdscr, TRUE);
 
    while (c != 'H') {
        c = getch();
        printw("basildi: %d '%c'\n", c, c);
    }
 
    // Temizlik
    endwin();
 
    return 0;
}

Ali
Mengu (Moderatör) #2
Kullanıcı başlığı: NONSERVIAM
Üye Tem 2009 tarihinden beri · 347 mesaj · Konum: Dersaadet
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
freenode'daki #d kanalinda sordum bunu sizin icin, soyle bir cevap verdiler:

[07:58] <|wilsonk|> mengu: you just have to convert the header and then include the lib on the command line via -l<libname> (or -L-l<libname>)
[08:01] <|wilsonk|> so you can use any builtin libc functions like printf in your code...just use "extern (C) int printf(char*,...);" near the top of your D file and then use printf  (libc is linked automatically)
[08:02] <|wilsonk|> I think you can also import tango.stdc.stdio: printf    in your D file and that should work
http://www.mengu.net - some kind of monster
Bu mesaj Mengu tarafından değiştirildi; zaman: 2009-08-08, 23:07.
acehreli (Moderatör) #3
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ı
Teşekkürler ama Türkçe bilmiyorlar mıydı?   :-p

Yani şunları anlatmış:

1) Ya C başlığını dönüştürmek gerekiyor, ya da programın başına gerektikçe extern (C)'ler eklemek gerekiyor

2) Derlerken satıra -L-lncurses yazmak gerekiyor (dmd tek -lncurses kabul etmiyor)

Tango da çok yaygın bir D kütüphanesi ve Phobos'la biraz çekişme halinde. :) Ben daha çok zaman darlığı nedeniyle Phobos'u öğrenmeye karar verdim.

Başlıkların nasıl dönüştürüldüklerini görmek için dmd ile gelen modüllere baktım ve biraz örneğin şunun gibi modüllerden kopya çektim:

  dmd/src/druntime/import/core/stdc/time.d

C programını D'ye şöyle geçirdim:

1) benim_ncurses.d isminde bir dosya yazdım:

module benim_ncurses;
 
extern (C):
 
enum TRUE = 1;
enum FALSE = 0;
 
alias void WINDOW;
 
WINDOW * initscr();
int cbreak();
int noecho();
int nonl();
 
int intrflush(WINDOW * win, bool bf);
 
// Hile: extern NCURSES_EXPORT_VAR(WINDOW *)   stdscr;
WINDOW * stdscr;
 
int keypad(WINDOW *win, bool bf);
 
int getch();
int printw(const char *fmt, ...);
int endwin();

<ncurses.h> oldukça uzun bir başlık; bütün bildirimleri tek tek dönüştürmek uzun iş. Kesin birileri yapmıştır aslında...

2) C programını D'ye sorunsuzca çevirdim:

import benim_ncurses;
 
void main()
{
    int c;
 
    // Baştan bunu cağırmak şartmış
    initscr();
 
    // Bunların çağrılması öneriliyor
    cbreak();
    noecho();
    nonl();
    intrflush(stdscr, FALSE);
    keypad(stdscr, TRUE);
 
    while (c != 'H') {
        c = getch();
        printw("basıldı: %d '%c'\n", c, c);
    }
 
    // Temizlik
    endwin();
}

3) Şöyle derledim:

  dmd -w -L-lncurses deneme.d

Çalıştı! :)

Ali
acehreli (Moderatör) #4
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ı
Bu programda bir değişiklik gerekiyor. Şu satır dmd 2.030'dan bu yana artık derlenemiyor:

acehreli on 2009-08-09, 00:01:
WINDOW * initscr();

Derleme hatası şöyle:

$ dmd -w -L-lncurses deneme.d
/usr/bin/ld: stdscr: TLS reference in deneme.o mismatches non-TLS definition in /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../libncurses.so section .bss
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../libncurses.so: could not read symbols: Bad value
collect2: ld returned 1 exit status
--- errorlevel 1

Onu gidermek için, benim_ncurses.d iliştiricisinde o bildirimin başına __gshared eklenebilir:

__gshared WINDOW * stdscr;

Artık derleniyor ve çalışıyor. Bunun nedeni şu sayfada anlatılıyor, ve sorun sanırım başka şekilde de çözülebiliyor:

  http://www.digitalmars.com/d/2.0/migrate-to-shared.html

Ali
canalpay (Moderatör) #5
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bu arada bende bir yerlerden alıntı yapıp iki üç şey yamalayıp bir şeyler denedim.

Kodlar burada :

http://ideone.com/mDksH

Kodda curses modülü var ve denediğim örnekler çalışıyordu. Ama cursesi bilmediğim için herşeyi deneyemedim. Sizde bakarsanız çok iyi olur. Eğer bu olursa SDL'yi bile binding ile kullanabileceğimizi sanıyorum.
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ı
Çok güzel... :)

Bir öneri: extern(C)'yi tekrarlamak yerine hepsinin başına bir kere yazılabilir:

extern(C):
// ... 

Ama gerek yok tabii...

Ali
canalpay (Moderatör) #7
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bende fark ettim.

Ama bunu tamamen ben çevirmedim.(Hatta hiç bir şey çevirmedim de diyebilirim.) Hatırlarsanız ben dün size bir şey demiştim. İçimdeki bir ses bcd projesindeki D'ye çevrilmiş bağlayıcıları çok kolay şuanki dmd ile çalışabilir hale getirebiliriz demiştim. Bende bugün kendime C++'nin ilk derleyicisine benzer bir derleyici yazmaya çalışırken sıkıldım ve bu içimdeki sesi dinlemeye karar verdim. Bu konuya baktım ve ne değişmiş onu tekrar kendime teyit ettirdim. Daha sonra bcd projesine baktım. curses'in kaynak kodunu aldım ve 3 yere __gshared ekledim. Bütün kodlar extern (c) bilmem ne diye yazıldığı için düzenlemek ile uğraşmadım.

Şuan curseste beklediğim tek hata __gshared konmamasından kaynaklanabilcek bir hata. Ama onun bile var olmadığını düşünüyorum.
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-21, 11:23:21 (UTC -08:00)