Forum: Diğer Konular RSS
Dilleri Birbirine Bağlamak İçin Bağlayıcı Yazılımı
İbrahim #1
Üye Eki 2015 tarihinden beri · 162 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Dilleri Birbirine Bağlamak İçin Bağlayıcı Yazılımı
Selamün Aleyküm;

Kodlarımızı bir dille yazıp birçok dilde kullanmak istediğimiz zamanlar oluyor. Bu durumlarda statik / dinamik kütüphaneler olarak kullanabiliyoruz. Lakin bu biraz meşakkatli olabiliyor. Ben de şöyle birşey düşündüm, mesela bir bağlayıcı olsa ve misal C++ kodlarını Python veyahut da başka bir dilde kullanılabilir hale getirse. Yani örneklemek gerekirse şöyle bir C++ kodumuz olsun:
class Test : public AbstractClass, private SubProp
{
private:
  // private üyeler
public:
  Test();
  Test(const std::string& str);
 
  void set_map(const std::map<std::string, std::string>& map)
  {
    // ...
  }
 
  std::map get_map() const
  {
    // ...
  }
};
Şimdi bu kodu Python'da şöyle kullanmak istiyoruz:
from Test import *;
 
def main():
    test_instance = Test()
    test_instance2 = Test('Hello!')
 
    test_instance.set_map({ 'name' : 'Ali', 'no' : '123' })
    result = test_instance.get_map()
Veyahut da Object Pascal'da şöyle kullanmak istiyoruz:
uses Test;
 
var
  testInstance  : Test;
  testInstance2 : Test;
  map           : TMap<string, string>;
begin
  testInstance := Test.Create;
  testInstance2 := Test.Create('Hi!');
  map := TMap<string, string>.Create;
  map.insert('name', 'Ali');
  map.insert('no', '123');
  testInstance.set_map(map);
  result := testInstance.get_map;
end.
Yalnız bunları kullanmak için C++ wrapper ve statik / dinamik bir kütüphane hazırlamadan kullanmak istiyoruz. Mesela "C++ tarafında şu şu sınıfı / nesneyi falan dilde kullanmak istiyorum" gibisinden bazı işaretlemeler mi koymalıyız? Mesela şöyle:
// C++
PASCAL_SINIFI class Test : public AbstractClass, private SubProp
{
  // ...
};
Bunun için bir bağlayıcı (linker) yazılabilir mi? Eğer evetse nasıl yazılabilir? Mantığı nasıl kurmalıyım?
Teşekkürler!
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4539 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bence en kolayı kütüphane kullanmak. Onu meşakkatli buluyorsan durum kötü. :)

Kütüphane çözümünün sorunu, dillerin ABI'lerinin (application binary interface) vs. farklı olması. O yüzden bu işin ortak dili olarak C'de karar kılmış durumdayız. Seçili diller kendi temel aldıkları dillerle de çalışabiliyorlar ama en yaygın olanı C. Bir de D gibi C++ ile çalışmayı hedefleyen diller var. D ne kadar C ile hemen hemen tam uyumlu olsa da C++ ile tam olamıyor. (Hata atma düzenekleri vs. farklı.)

D'den örnek vermek gerekirse, kullandığımız ilinti dosyaları (C ve C++ kütüphanelerinin D binding'leri) gösterdiğin kodları destekliyor.

Belki de yanlış anlıyorum ama diller anlamsal olarak yakınsa (yani aynı semantic kavramlarına sahipse) dilden dile çevirme de yapılıyor. Ama örneğin Python gibi çöp toplayıcılı dildeki bir dictionary'yi C++'ın std::map'ine dönüştürünce yaşam süreçleri konusunu bir şekilde otomatikleştirmek gerek.

Her iki konu D'de görüldü:

  • extern(C) ve extern(C++) yolu ile C ve C++ kütüphanelerini kullanabiliyoruz

  • dmd derleyicisinin ön tarafı (frontend), C++'tan D'ye çeviren bir araçla otomatik olarak dönüştürüldü; yakında arka tarafı da dönüştürülecek

Ali
İbrahim #3
Üye Eki 2015 tarihinden beri · 162 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Bence en kolayı kütüphane kullanmak. Onu meşakkatli buluyorsan durum kötü. :)
:) Evet aslında dediğiniz gibi kütüphane kullanmak daha kolay olabiliyor ama C sarmalayıcısı (wrapper) yazmak zorundayız ve bu gerçekten programlama dillerine uydurmayı bazen zorlaştırıyor. Mesela Google'ın Firebase aracı var. Bu Firebase C++ dili kullanılarak yazılmış lakin asıl kaynak kodlar açık kaynak kodlu değil ve statik kütüphane kullanılıyor. .h başlık dosyaları ile de kullanabiliyoruz. Eğer bu kütüphaneyi Object Pascal'da kullanmak istersek .h dosyalarını okuyarak bir C sarmalayıcısı yazmak zorundayız. Bu benim için kolay olabiliyor ama ben geliştirmeye çalıştığım aracı başkaları daha kolay kullanabilsin istiyorum. Yani geliştirici C++ kodunu sarmalayıcılarla parçalayacağına direk C++ sınıflarını, değişkenlerini, yapılarını vs. vs. direk olarak kullanabilsin istiyorum. Mesela Qt da C++ kodlarını QML'de kullanırken bize böyle bir imkan sağlıyor.

D'den örnek vermek gerekirse, kullandığımız ilinti dosyaları (C ve C++ kütüphanelerinin D binding'leri) gösterdiğin kodları destekliyor.
D'de extern (C++) kullanarak C++ kodlarını nasıl kullandığına baktım ve benim yapmak istediğim birşeyi D için yapmışlar. Ben de buna benzer bir yapıyı Object Pascal için yapmak istiyorum. Aslında C++ ve Object Pascal yapı olarak birbirlerine çok benziyorlar. Lakin Object Pascal'da olan bazı kurallar C++'da, C++'da olan bazı kurallar da Object Pascal'da yok. Mesela Object Pascal'da öznitelikler (properties) var:
property name : String read getName write setName;
Böyle bir yapı C++'da olmadığı için şöyle birşey tasarlamak istiyorum:
// C++ kodu
std::string name; // ya da char* name; de olabilir
//...
PASCAL_PROPERTY(name READ getName WRITE setName)
Bu tür bir yapı oluşturmak istiyorum. Bu PASCAL_PROPERTY bir önişlemci kodu olabilir. Hatta kabaca şöyle bir yapı olabilir:
PASCAL_NAMESPACE namespace abc
{
  PASCAL_CLASS class Test
  {
  private:
    std::map _map;
    std::string _str;
    std::string _name;
 
    void setName(const std::string& str);
    std::string getName() const;
  public:
    Test();
    Test(const std::map& map, const std::string& str);
    
    PASCAL_PROPERTY(std::string name READ getName WRITE setName)
 
    PASCAL_METHOD void hello(const char* name) const;
  };
}
Bunu bir bağlayıcı ile Object Pascal'da şuna çevireceğim (Bağlayıcı derleme aşamasında bu önişlemcileri otomatik Pascal dosyasına dönüştürecek, mesela burada abc.pas dosyası oluşturup içine bunları koymalı):
unit abc; // C++ Namespace
 
interface
 
type
  Test = class // C++ Test Class
  private
    _map: TMap;    // C++ : std::map _map;
    _str: String;  // C++ : std::string _str;
    _name: String; // C++ : std::string _name;
 
    procedure setName(const str: String);
    function getName : String;
  public
    constructor Create; overload;
    constructor Create(const map: TMap; const str: String); overload;
 
    // C++ : PASCAL_PROPERTY
    property name: string read getName write setName;
 
    // C++ : PASCAL_METHOD
    procedure hello(const name: PAnsiChar);
  end;
 
implementation
end.
Böyle bir bağlayıcı geliştirmek için nasıl bir yol izlenmeli? std::map vb. işler için de TMap(const std::map& map) gibi yeni sınıflar yazacağım. Bu iş için C++'da bu tür önişlemcilere nasıl komutlar verebilirim?
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4539 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
İbrahim:
direk C++ sınıflarını, değişkenlerini, yapılarını vs. vs. direk olarak kullanabilsin istiyorum

Onun çok kolay olabilmesi için her dilin her dili anlaması gerekir. D örneğinden bakarsak D'nin C++ başlık dosyalarını dosyalarının doğrudan kullanamamasının nedeni, D derleyicisinin aynı zamanda C++ derleyicisi de olmasının gerekmesi. Çok zor bir iş.

D'de extern (C++) kullanarak C++ kodlarını nasıl kullandığına baktım ve benim yapmak istediğim birşeyi D için yapmışlar

Evet, C++'ın destekleme konusunda bildiğim kadarıyla D en ileri konumda.

Bu PASCAL_PROPERTY bir önişlemci kodu olabilir. Hatta kabaca şöyle bir yapı olabilir:

Evet, bence olabilir.

Bağlayıcı derleme aşamasında bu önişlemcileri otomatik Pascal dosyasına dönüştürecek

İlgisiz olarak, bağlayıcı sözcüğünü linker'ın karşılığı olarak kullanıyoruz. Bence belki çevirici ve dönüştürücü gibi başka bir sözcük bulmak gerek. :)

Böyle bir bağlayıcı geliştirmek için nasıl bir yol izlenmeli?

Maalesef benim hazırda cevabım yok. :( Object Pascal'da attribute olanağı var mı? Bazı değişkenlerin C++'ta yaşadıklarını bildirmek için kullanılabilir. Hatta, Doxygen gibi bazı araçların yaptığı gibi özel açıklama kodları kullanabilirsin. Örneğin, gösterdiğin kodlardaki // C++ : std::map _map; gibi açıklamalardan doğrudan yararlanabilirsin. Yani, programcı açıklamalarla tarif eder, senin dönüştürücü de ne yapacağını bilebilir. Belki... :)

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-12-18, 00:55:01 (UTC -08:00)