Platformlar arası uyumluluğu sağlama teknikleri (C ++)?


13

En eski C ++ projelerimden birini (çerçeveye göre) çapraz platform olması gerekiyordu. Projeyi tamamen Windows ve Visual Studio'da geliştirdim, kütüphanelerin hepsi çapraz platform olduğundan, daha sonra "daha sonra" OSX derlemesini yapmanın önemsiz olacağını düşünüyorum. Bu durum böyle değildi, ancak "Windows kodu" düzgün çalışmıyor ve bazı derleme hataları düzeltildi.

Kodun tüm platformlarla uyumlu olmasını sağlamak için önceden hangi teknikler mevcuttur? Tüm platformları aynı anda geliştirmek, böylece farklı platform sürümlerini birbiri ardına geliştirmek yerine, yeni özellikler eklendiğinde kodu her platforma karşı aynı anda test etmek mi? (*)

Özellikle, araçlara bağlı olmayıp, hangi araçların kullanıldığına bakılmaksızın platformlar arası uyumluluğa yardımcı olan "geliştirme süreçleri" ni özellikle tavsiye ediyoruz. Yukarıdaki gibi (*).


Özellikle WDL-OL ( https://github.com/olilarkin/wdl-ol ) ve bazı platformlar arası DSP kütüphaneleri ile bir VST eklentisi geliştiriyorum . WDL-OL projeleri hem VS hem de Xcode projelerini oluşturdu, ancak sanırım problemler kütüphanelerden geliyor ve derleyicilerdeki farklılıklar.


1
taşınabilirliği sağlamanın bir yolu yoktur , sadece taşınabilirliği artırmanın / en üst düzeye çıkarmanın yolları vardır
phuclv

ve bu neden kopya değil? Benzer soruların olduğuna inanıyorum
phuclv

Başvurunuz ne yapıyor? Nasıl kullanırdın? Komut satırında mı, yoksa bazı grafik arayüzlerde mi? Sorunuzu geliştirmek için lütfen düzenleyin .
Basile Starynkevitch

Ve hangi çerçeveyi kullanıyorsunuz?
Basile Starynkevitch

Yanıtlar:


15

Taşınabilir kod oluşturmak çok zor olabilir.

Öncelikle dile ilişkin bazı bariz tavsiyeler:

  • standart C ++ kullanın ve tanımlanmamış davranışlardan dikkatlice kaçının
  • öncelikle standart kütüphaneye (ve boost gibi taşınabilir kütüphanelere ) güvenebilirsiniz
  • her zaman beklenen tüm başlıkları içerir. Başka bir başlıkta yer aldığından (yani belirli bir uygulamada !) Bir başlığa ihtiyacınız olmadığını varsaymayın : bu derleme hatalarına neden olabilir
  • derleyici tarafından desteklenen ancak C ++ standardı tarafından garanti edilmeyen yapılardan kaçının (örn. anonim yapı veya değişken uzunluk dizisi ): derleme hatalarına neden olabilir.
  • uyumluluğu zorlamanıza yardımcı olması için derleyici seçeneklerini kullanın (derleyiciye özgü uzantıları devre dışı bırakmak, döndürülen uyarı iletileri düzeyini en üst düzeye çıkarmak)
  • kodun çalışmasının yeterli olmadığını unutmayın: birçok uygulamaya bağlı taşınabilirlik tuzakları vardır: (hatta temel) veri türlerinin boyutu, varsayılan olarak imzalanabilen veya imzalanamayan karakterler , endianlıkla ilgili varsayımlar , bunlardaki ifadelerde değerlendirme sırası yan etkileri vb. kullanın .

Sonra birkaç tasarım önerisi:

  • Eşdeğer işletim sistemi işlevselliğine alternatif standart kitaplık tercih et
  • İşletim sistemi bağımlılıklarının kullanımını olabildiğince izole edin (örneğin, koşullu derleme ile kontrol edilen bir sarma işlevinde)

Sonunda hassas noktalar:

  • karakter kodlaması: birçok sistemde utf8'e güvenebilirsiniz . Ancak Windows için sistem ansi veya utf-16 beklediğinden daha hassastır. Sen elbette (gibi bir typedef güvenebilirsiniz TCHAR), ancak bu daha sonra (örneğin standart kütüphane ile birlikte zorlu olabilir coutvs wcoutkullanılacak bağlı kullanılıyorsa charveya wchar_t)
  • GUI / grafik / gelişmiş G / Ç için beklentilerinize / gereksinimlerinize uygun taşınabilir bir kütüphane bulamazsanız, işletim sistemine özgü bileşenleri izole etmek için genel mimariyi tasarlayın. Burada birçok farklı etkileşim ve kavram nedeniyle sarmalayıcılar yeterli olmayabilir.
  • Soyut fabrika (işletim sistemine özgü kullanıcı arayüzü gibi ilgili nesnelerin ailelerini tasarlamak için ideal) veya arabulucu (ilgili nesnelerin aileleri arasında işbirliğini uygulamak için ideal ) gibi bazı ilginç tasarım modellerinden yararlanın ve bunları koşullu derleme ile birlikte kullanın .

Ancak bunlar sadece tavsiye niteliğindedir. Bu alanda kesinlik kazanamazsınız.


-Wall -Wextra -Werror
boru

1
@pipe Ayrıca olmalısın -pedantic.
5gon12eder

@ 5gon12eder Bu cevap bağlamında çok iyi bir nokta.
boru

11

Kodun, onu oluşturmak, çalıştırmak ve orada test etmek dışında bir platformla uyumlu olduğunu garanti edebilecek hiçbir şey yoktur. Bu nedenle, tüm aklı başında insanların yaklaşımı, inşa edilmesi, çalıştırılması ve test edilmesi gereken her platformda uygulamalarını oluşturmak, çalıştırmak ve test etmektir.

Sürekli Entegrasyon (CI), küçük platformlar için bu yükü adil bir şekilde hafifletebilir, çünkü bazı platformlar için (çoğunlukla Linux) ucuz veya ücretsiz yapı aracıları alabilir, Windows'ta geliştirmenizi yapabilir ve bir sorun olduğunda Linux'a dönebilirsiniz.

OSX CI oldukça zor.


Hiçbir söz yok, CI nedir?
mavavilj

5
Sürekli Entegrasyon - temel olarak sizin için derlemeler ve testler çalıştıran bir grup sunucu.
DeadMG

@DeadMG Mozilla Tinderbox gibi mi?
Damian Yerrick

1
Travis CI ücretsiz OSX yapı ana makineleri sağlar
Daenyth

Sadece Cmake'yi kullan.
raaj

9

"Geliştirme süreçleri" için soran ve birincil geliştirme platformu Visual Studio ile Windows ise o zaman "windows.h" dahil olmadan projenizi oluşturmayı denemenizi öneririz. Kodunuzu yeniden düzenlemeniz gereken birçok yere yönlendirecek birçok derleme hatası alacaksınız. Örneğin, 'DWORD' #defined olmayacak ve onu uint32_ther yerde değiştirmeniz gerekecek (google for stdint.hve tamsayı türleri ve bunların platformlar arası tanımları hakkında yararlı bilgiler bulacaksınız). Ardından, Win32 API'ya yapılan tüm çağrıları değiştirmeniz gerekir, örneğin,Sleep()platformlar arası eşdeğeriyle (yine Google, yığın * .com sitelerinde alakalı soruları ve cevapları gösterecek en iyi arkadaşınızdır). Muhtemelen kodunuz için ilgili tüm platformlar arası değiştirmeleri bulmayı başaramayacaksınız ve include "windows."direktifinizi iade etmeli ancak altına koymalısınız #ifdef _WIN32- daha fazla ayrıntı burada

Daha somut sorular sormaya ve yanıt almaya devam edin - bu "geliştirme süreci ne olmalı" için genel öneri

EDIT 1 Başka bir önerim, Windows geliştirme makinenizde (Visual Studio ile birlikte) gcc ve / veya clang kullanmaktır


3

Bahsettiğiniz "bazı derleme hatalarına" bağlıdır. Ne olduklarını bilmeden, spesifik olmak imkansız.

Windows / Linux / iOS / Android / Mac için platformlar arası kodum var. Her yeni platform, ilk eklendiğinde bazı ekstra hatalar ve uyarılar getirdi. Hangi yapıların sorun getirdiğini hızlı bir şekilde öğreneceksiniz. Ya onlardan kaçının ya da farklılıkları #ifdefs ile bir başlığa dönüştürün . #ifdefKodunuzun içindeki platformlar arasında hiçbir zaman çalışmayın .

Bir örnek:

void myfunction(MyClass &);
myfunction(MyClass());

Geçici bir örneğini oluşturur MyClasssonra silinir myfunctiongeri döndü. C ++ derleyicilerimden bazılarında bu örnek okuma / yazma (ve geçici olması ve yakında yok edilmesi gerçeği derleyiciyi endişelendirmez). Diğerleriyle birlikte, myfunctiona almak için yeniden tanımlanması gerekir const MyClass &, ya da derleyici şikayet eder. C ++ standardının ne söylediği veya hangi derleyicinin doğru ve hangisinin yanlış olduğu önemli değildir. Ya (a) için birkaç kez bildiğim hataya rastladığında türünde bir geçici değişken bildirmek MyClassve bu geçiş myfunctionveya (b) başvuru beyan constiçinde myfunctionve kullanımı mutableoraya buraya deconstify için.

Alt satır: deneyim biriktirin ve kendi kodlama standartlarınızı geliştirin.


2
Bu MSVC'nin yanlış bir özelliğidir. Demek istediğin, 1 sistem üzerinde gelişmenin bunların içine girmesine izin vermesi durumunda, alınan nokta. Ama bu özel şey yapmanız gereken bir şey değil.
JDługosz

1
Birden çok takım zinciri kullanmanın iyi bir yolu, kabul ettikleri ortak altkümenin, her birinin ayrı ayrı kabul ettiklerinden daha doğru, standartlara uygun C ++ olma ihtimalinin daha yüksek olmasıdır. Sizin durumunuzda, gösterilen kod standart tarafından açıkça yanlıştır ve bahsi geçen düzeltmelerin her ikisi de geçerli alternatiflerdir. Standardın ne dediğinin önemli olduğunu söyleyebilirim .
5gon12eder

1
Veya platformlar arası C ++ standardının söylediklerinden daha kısıtlayıcı olduğunu söyleyebilirim. Başka bir deyişle, standart bunu söylemiş olsa bile, hala desteklemeniz gereken platformlar için en düşük ortak paydalara (veya en az satıcı kapasitesine) tabi olursunuz. Diyelim ki C ++ 11'i hariç tutmak zorunda olan çok sayıda açık kaynak kütüphanesi var, çünkü bileşenlerinin bir kısmı (vatandaşlarda olduğu gibi) C ++ 11 yeteneğine sahip değil.
rwong

3

Taşınabilirliğe yardımcı olmanın olası bir yolu, yalnızca C ++ 11 standardı tarafından sağlanan bildirimlere ve özelliklere ve POCO & Qt gibi platformlar arası kütüphaneler ve çerçeveler kullanmak olabilir .

Ancak bu bile hataya dayanıklı değildir. Aforizmayı hatırla

taşınabilir bir program diye bir şey yoktur, sadece başarıyla taşınan programlar vardır (belirli bir platforma)

Uygulama, disiplin ve çok fazla deneyim ile, bir programı başka bir platforma taşımak genellikle hızlı bir şekilde yapılabilir. Ancak deneyim ve know-how çok önemlidir.


1
Diğer bir tavsiye ise, taşıma farklı kişiler ve ekip tarafından yapıldığında, kod değişikliklerinin ana hatta yeniden entegre edilmesi gerektiğidir. Aksi takdirde, platform farklılıkları bunu yapan ekip tarafından biriktirilen bir bilgi haline gelir.
rwong
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.