Thread overview
Dilleri Birbirine Bağlamak İçin Bağlayıcı Yazılımı
Sep 13, 2017
İbrahim
Sep 14, 2017
İbrahim
September 13, 2017

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!

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 13, 2017

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

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 14, 2017

Alıntı:

>

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.

Alıntı:

>

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?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 14, 2017

Alıntı (İ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ş.

Alıntı:

>

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.

Alıntı:

>

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

Evet, bence olabilir.

Alıntı:

>

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. :)

Alıntı:

>

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

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]