26 Ocak 2024
C#'den C++ kod çeviricisinin tasarımı ve geliştirilmesi yalnızca CodePorting tarafından gerçekleştirildi. Bu, bellek modeli ve diğer yönlerden farklı olan birçok araştırma, çoklu yaklaşım ve test gerektirdi. Sonunda iki çözüm seçildi. Bunlardan biri şu anda Aspose ürünlerinin C++ sürümleri için kullanılıyor.
Şimdi kod çeviricisinde kullandığımız teknolojileri açıklama zamanı geldi. Çevirici, C# ile yazılmış bir konsol uygulamasıdır, bu da tipik dizileri gerçekleştiren komut dosyalarına gömülmesini kolaylaştırır, örneğin çevir-derle-test. Ayrıca, aynı işlemi düğmelere tıklayarak yapmanıza olanak tanıyan bir GUI bileşeni bulunmaktadır.
Sözdizimi analizi, eski nesil çeviricinin NRefactory kütüphanesi tarafından ve yeni nesil çeviricinin Roslyn tarafından gerçekleştirilmektedir.
Çevirici, bilgi toplamak ve çıktı C++ kodu oluşturmak için birkaç AST ağacı gezinmesi kullanır. C++ kodu için AST temsili oluşturulmaz, bunun yerine çıktı kodunu saf metin biçiminde ele alırız.
Çeviriciyi ayarlamak için ekstra bilgi gerektiren birçok durum vardır. Bu bilgi, seçenekler ve nitelikler aracılığıyla iletilir. Seçenekler, genellikle tüm projeye uygulanır. Genellikle, kodu ayrıştırırken kullanılan sınıf dışa aktarma makro adını veya C# koşullu sembollerini belirtmek için kullanılırlar. Nitelikler, türler ve varlıklara uygulanır ve bunlar için bazı özel bilgiler sağlar, örneğin çevrilen kodda hangi sınıf üyelerinin const
veya mutable
niteliklerini gerektirdiğini işaretler veya hangi varlıkların çeviriden hariç tutulması gerektiğini belirtir.
C# sınıfları ve yapıları C++ sınıflarına dönüştürülür. Üyeleri ve kaynak kodları en yakın benzerlere dönüştürülür. Genel türler ve yöntemler C++ şablonlarına eşlenir. C# referansları akıllı işaretçilere (paylaşılan veya zayıf) çevrilir. Referans sınıfları Kütüphane'de tanımlanır. Kod çeviricisinin diğer iç ayrıntıları ayrı bir makalede açıklanacaktır.
Bu nedenle, C# den C++'a çevrilen proje, .NET kütüphanelerinin yerine kendi Kütüphanemize dayanır:
C# kod çevirici Kütüphanesini ve çevrilen projeleri oluşturmak için Cmake kullanıyoruz. Şu anda, VS 2017 ve 2019 (Windows), GCC ve Clang (Linux) derleyicilerini destekliyoruz.
Daha önce de belirtildiği gibi, .NET uygulamalarımızın çoğu, şunlar dahil olmak üzere üçüncü taraf kütüphaneler üzerinde ince adaptörlerdir:
Çevirici ve Kütüphane birçok testle kaplıdır. Kütüphane testleri GoogleTest çerçevesini kullanır. Çevirici testleri çoğunlukla NUnit/xUnit ile yazılmıştır ve çeşitli kategorilere ayrılmıştır, bu da şunları sağlar:
Sürüm kontrol sistemi olarak GitLab kullanıyoruz. Sürekli entegrasyon için Jenkins kullanıyoruz. Çevrilen ürünler NuGet paketleri olarak ve indirilebilir arşivler olarak sunulmaktadır.
Bu projede çalışırken birçok farklı sorunla karşılaştık. Bunlardan bazıları bekleniyordu, bazıları ise yolda ortaya çıktı:
Object
türü için herhangi bir yerine koyma yapısına sahip değil ve çoğu kütüphane sınıfı RTTI'ye sahip değil. Bu, .NET türlerini STL türlerine eşlemeyi imkansız hale getiriyor.yield
).Tüm bunlara rağmen, kod çevirici projesi teknik açıdan çok ilginçtir ve akademik karmaşıklığı bizi sürekli olarak yeni şeyler öğrenmeye zorlar.
Kod çevirici projesi üzerinde çalışırken, ilginç bir akademik kod çevirme görevini çözen bir sistem başarıyla uyguladık. Aspose kütüphanelerini, çalışması beklenmeyen diller için aylık olarak yayınladık.
Kod çevirici hakkında daha fazla makale yayınlamayı planlıyoruz. Bir sonraki makale, C# yapılarının nasıl C++ yapılarına eşlendiği dahil olmak üzere dönüşüm sürecini ayrıntılı olarak açıklayacaktır. Bir diğeri bellek yönetim modelini ele alacaktır.
Sorulan sorulara en iyi şekilde yanıt vermeye çalışacağız. Okuyucular kod çevirici geliştirmenin diğer yönleriyle ilgilenirse, daha fazla makale yazmayı düşünebiliriz.