Forum: D Programlama Dili RSS
linux dinamik kütüphane çağırma
kaaninel #1
Üye Ock 2013 tarihinden beri · 22 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: linux dinamik kütüphane çağırma
Windows ortamında rahatlıkla dinamik olarak dll çağırabiliyorum aynı şekilde linuxda da so kütüphanelerini çağrımak istiyorum ama windowsta FARPROC diye bir şey kullanıyoruz ve sanırım linux için bunu nasıl yapabiliriz ?
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ı
Galiba Linux bu konuda Windows'dan daha geride ama kısıtlamanın ne olduğundan emin değilim. En azından bazı kullanımlar çalışıyor. Örnek olarak libm.so içinde tanımlı olan gamma() işlevine bakalım:
import std.stdio;
 
/*
 * libm.so içinde tanımlı olan bir işlev. Aslında D'de ilintileri de var ama
 * gösterim amacıyla internet'ten öğrendiğim bildirimini burada elle
 * yapıyorum.
 */
extern(C) double gamma(double);
 
void main()
{
    writefln("Sonuç: %s", gamma(1.5));
}
libm.so ayrıcalıklı çünkü şu komutla bile derleniyor:

$ dmd deneme.d

Bunun nedeni, dmd bazı kütüphaneleri otomatik olarak bağlıyor. Bunu -v ile görebiliriz:

$ dmd deneme.d -v
...
gcc deneme.o -o deneme -m64 -L/usr/lib64 -L/usr/lib -Xlinker --no-warn-search-mismatch -Xlinker --export-dynamic -l:libphobos2.a -lpthread -lm -lrt

Yani aslında o en son bağlama adımını gcc'ye yaptırıyor. Oradaki -lm libm.so'yu temsil ediyor. Dolayısıyla, libxyz.so diye bir kütüphane varsa, yukarıdaki son adımdan önce -c ile kendi dosyamızı derlemek ve son adımın sonuna -lxyz eklemek yeterli olmalı:

dmd deneme.d -c       <-- deneme.o'yu oluşturur
gcc deneme.o -o deneme -m64 -L/usr/lib64 -L/usr/lib -Xlinker --no-warn-search-mismatch -Xlinker --export-dynamic -l:libphobos2.a -lpthread -lm -lrt -lxyz

Yukarıda yazdıklarıma ek olarak DConf'ta Martin Nowak'ın konuşması var. O da dinamik kütüphaneleri çalışma zamanında açmayı anlatıyordu. (Ayrıntılarını hatırlamıyorum. :-/)

Ali
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ı
Yazmayı unutmuşum: Bir programın veya kütüphanenin başka hangi kütüphanelere bağımlı olduğu da ldd programı ile görülebiliyor:

$ ldd deneme
    linux-vdso.so.1 =>  (0x00007fff598ea000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003016e00000)
    libm.so.6 => /lib64/libm.so.6 (0x0000003016600000)
    librt.so.1 => /lib64/librt.so.1 (0x0000003017600000)
    libc.so.6 => /lib64/libc.so.6 (0x0000003016200000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003015e00000)

Ali
kaaninel #4
Üye Ock 2013 tarihinden beri · 22 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Aslında tam olarak böyle değil. Bu yazdığınız kodlarda so dosyalarına compile time erişiyor ama bizim ihtiyacımız olan şey bu so dosyalarını runtime olarak erişip içindeki fonksiyonları çağırmak.

Runtime.loadLibrary ile bu dosyalara erişebiliyoruz ama içerisindeki işlevlere windows ortamında farproc ile erişebilirken linuxda bunun karşılığı ne bilmiyorum. Bunun linux için karşılığı var mı?

Kaan
acehreli (Moderatör) #5
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ı
kaaninel:
Bu yazdığınız kodlarda so dosyalarına compile time erişiyor

"Erişiyor" derken hangi kütüphanede bulunduğunu belirliyor ama yine de o kodları çalışma zamanında çağırıyor.

ama bizim ihtiyacımız olan şey bu so dosyalarını runtime olarak erişip içindeki fonksiyonları çağırmak.

Linux'ta dlopen() ve arkadaşları kullanılır ama D'de denemedim.

Martin Nowak'ın sunumu içinde bulunduğumuz durumu ve var olan çözümleri anlatıyor:

  http://dconf.org/2013/talks/nowak.html

Ali
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ı
(Not: Bütün DConf saydamlarının bağlantılarında fazladan bir "/2013" var. Elle silmek gerekiyor.)

Önce C ile bir .so oluşturalım:
// deneme.c
int benim_islevim(int i)
{
    return i * 2;
}

$ gcc deneme.c -shared -o libxyz.so

Şöyle bir D programı ile açıp kullanabiliriz:
import std.stdio;
import std.string;
import core.sys.linux.dlfcn;
 
extern(C) int benim_islevim(int);
alias İşlevTürü = int function(int);
 
int main()
{
    void * kütüphane = dlopen("./libxyz.so", RTLD_NOW);
 
    if (!kütüphane) {
        stderr.writefln("Kütüphane açılamadı");
        return 1;
    }
 
    auto işlev = cast(İşlevTürü)dlsym(kütüphane, "benim_islevim");
 
    if (!işlev) {
        stderr.writefln("İşlev bulunamadı");
        return 1;
    }
 
    writefln("Sonuç: %s", işlev(10));
 
    return 0;
}
Programı derlerken libdl'yi de belirtmek gerek:
$ dmd deneme.d -L-ldl
Çıktısı:
$ ./deneme
Sonuç: 20

Ali
Avatar
Salih Dinçer #7
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Bunları öğrendiğimiz ve/veya yazıya döktüğümüz çok iyi oldu, teşekkürler...

Linux'a daha çok önem veriyorum. Gerçi Windows kullanıcıları da azımsanamayacak derecede fazla ama Linux ile yapabileceklerimiz çok fazla...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
kaaninel #8
Üye Ock 2013 tarihinden beri · 22 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Çok teşekkürler kodları buna göre düzenledim. Rhodeus Script i Ubuntu x64 de çalıştırmayı deniyorum ve sadece hata çıkıyor karşıma ama kodları düzenleyip crossplatform desteklemesini sağlayacağım.

Kaan
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-18, 00:24:23 (UTC -08:00)