web-dev-qa-db-fra.com

Les applications C ++ sont-elles multiplateformes?

L'une des premières choses que j'ai apprises en tant qu'étudiant était que les applications C++ ne s'exécutent pas sur différents systèmes d'exploitation. Récemment, j'ai lu que les applications C++ basées sur Qt fonctionnent partout. Alors, quoi de neuf? Les applications C++ sont-elles multiplates-formes ou non?

47
Antony
  1. Compatible avec le code source. Si je compile le code source, est-ce qu'il s'exécutera partout.

  2. Compatibilité API/ABI. Le système d'exploitation fournit-il l'interface à ses composants d'une manière que le code comprendra?

  3. Compatibilité binaire. Le code est-il capable de s'exécuter sur l'hôte cible?

Compatible avec le code source

C++ est une norme qui définit comment les structures, la mémoire et les fichiers peuvent être lus et écrits.

#include <iostream>
int main( int argc, char ** argv )
{
     std::cout << "Hello World" << std::endl;
}

Le code écrit pour traiter les données (par exemple grep, awk, sed) est généralement multiplateforme.

Lorsque vous souhaitez interagir avec l'utilisateur, les systèmes d'exploitation modernes ont une interface graphique, ceux-ci ne sont pas multiplateformes et entraînent l'écriture de code pour une plate-forme spécifique.

Les bibliothèques telles que qt ou wxWidgets ont des implémentations pour plusieurs plates-formes et vous permettent de programmer pour qt au lieu de Windows ou iOS, avec le résultat étant compatible avec les deux.

Le problème avec ces bibliothèques anonymisées, c'est qu'elles retirent certains des avantages spécifiques de la plate-forme X dans un souci d'uniformité entre les plates-formes.

Des exemples de cela seraient sur Windows en utilisant la fonction WaitForMultipleObjects, qui vous permet d'attendre que différents types d'événements se produisent, ou la fonction fork sur UNIX, qui permet deux des copies de votre processus à exécuter avec un état partagé significatif. Dans l'interface utilisateur, les formulaires ont un aspect et un comportement légèrement différents (par exemple, sélecteur de couleurs, maximiser, minimiser, la possibilité de suivre la souris à l'extérieur de votre fenêtre, le comportement des gestes).

Lorsque le travail que vous devez effectuer est important pour vous, vous pouvez finir par vouloir écrire du code spécifique à la plate-forme pour tirer parti des avantages de l'application spécifique.

La bibliothèque Csqlite est largement du code multiplateforme, mais son bas niveau IO est spécifique à la plate-forme, donc il peut garantir l'intégrité de la base de données (qui les données sont vraiment écrites sur le disque).

Ainsi, des bibliothèques telles que Qt fonctionnent, elles peuvent produire des résultats qui ne sont pas satisfaisants et vous finissez par avoir à écrire du code natif.

Compatibilité API/ABI

Différentes versions d'UNIX et de Windows ont une certaine forme de compatibilité entre elles. Ceux-ci permettent à un binaire construit pour une version de l'OS de s'exécuter sur d'autres versions de l'OS.

Sous UNIX, le choix de votre machine de génération définit la compatibilité. La révision de système d'exploitation la plus basse que vous souhaitez prendre en charge devrait être votre machine de génération et elle produira des binaires compatibles avec les versions mineures ultérieures jusqu'à ce qu'ils apportent une modification définitive (obsolète une bibliothèque).

Sous Windows et Mac OS X, vous choisissez un SDK qui vous permet de cibler un ensemble d'OS avec les mêmes problèmes de rupture des modifications.

Sous Linux, chaque révision du noyau est ABI incompatible avec toute autre, et les modules du noyau doivent être recompilés pour chaque révision du noyau.

Compatibilité binaire

Il s'agit de la capacité du CPU à comprendre le code. C'est plus complexe que vous ne le pensez, car les puces x64 peuvent être capables (selon la prise en charge du système d'exploitation) d'exécuter du code x86.

Généralement, un programme C++ est empaqueté à l'intérieur d'un conteneur (exécutable PE, format ELF) qui est utilisé par le système d'exploitation pour décompresser les sections de code et de données et pour charger des bibliothèques. Cela fait que le programme final a des incompatibilités binaires (type de code) et API (format du conteneur).

Aujourd'hui également, si vous compilez une application Windows x86 (ciblant Windows 7 sur Visual Studio 2015), le code peut ne pas s'exécuter si le processeur ne dispose pas d'instructions SSE2 (CPU âgé d'environ 10 ans).

Enfin, lorsque Apple est passé de PowerPC à x86, ils ont fourni une couche d'émulation qui permettait à l'ancien code PowerPC de s'exécuter dans un émulateur sur la plate-forme x86.

Donc, en général, l'incompatibilité binaire est une zone trouble. Il serait possible de produire un système d'exploitation qui a identifié des instructions non valides (par exemple SSE2) et dans l'erreur, a émulé le comportement, cela pourrait être mis à jour à mesure que de nouvelles fonctionnalités sortent et maintient votre code en cours d'exécution, même s'il est incompatible binaire.

Même si votre plate-forme est incapable d'exécuter une forme de jeu d'instructions, elle pourrait être émulée et se comporter de manière compatible.

61
mksteve

Le C++ standard est multiplateforme dans le sens "écrire une fois, compiler n'importe où", mais pas dans le sens "compiler une fois, exécuter n'importe où".

Cela signifie que si vous écrivez un programme en C++ standard, vous pouvez le compiler puis l'exécuter sur n'importe quel environnement cible ayant une implémentation conforme standard de C++.

Vous ne pouvez cependant pas compiler votre programme sur votre machine, expédier le binaire puis vous attendre à ce qu'il fonctionne sur d'autres cibles. (Du moins pas en général. On peut bien sûr distribuer des binaires à partir de code C++ dans certaines conditions, mais ceux-ci dépendent de la cible réelle. Il s'agit d'un champ large.)


Bien sûr, si vous utilisez des fonctionnalités supplémentaires non standard comme les tableaux à longueur variable de gcc ou les bibliothèques tierces, vous ne pouvez compiler que sur des systèmes qui fournissent ces extensions et bibliothèques.

Certaines bibliothèques comme Qt et Boost sont disponibles sur de nombreux systèmes (ces deux sur Linux, Mac et Windows au moins je crois), donc votre code restera multiplateforme si vous les utilisez.

58
Baum mit Augen

Vous pouvez réaliser que votre source compile sur diverses plates-formes, vous donnant divers binaires de la même base source.

Ce n'est pas "compiler une fois, exécuter n'importe où avec une VM appropriée" comme Java ou C # faites-le, mais "écrire une fois, compiler n'importe où avec un environnement approprié "la façon dont C l'a fait tout le temps.

Étant donné que la bibliothèque standard ne fournit pas tout ce dont vous pourriez avoir besoin, vous devez rechercher des bibliothèques tierces pour fournir cette fonctionnalité. Certains frameworks - comme Boost, Qt, GTK +, wxWidgets etc. - peuvent fournir cela. Étant donné que ces frameworks sont écrits de manière à ce qu'ils compilent sur différentes plates-formes, vous pouvez obtenir une fonctionnalité multiplateforme dans le sens susmentionné.


Il y a plusieurs choses à savoir si vous voulez que votre code C++ soit multiplateforme.

La chose évidente est la source qui fait une hypothèse sur les types de données . Votre long peut être 32 bits ici et 64 bits là-bas. L'alignement du type de données et le remplissage de la structure peuvent différer. Il existe des moyens de "jouer en toute sécurité" ici, comme size_t/size_type/uint16_t typedefs etc., et des façons de se tromper, comme wchar_t et std::wstring. Il faut de la discipline et de l'expérience pour "bien faire les choses".

Tous les compilateurs ne sont pas créés égaux. Vous ne pouvez pas utiliser toutes les dernières fonctionnalités du langage C++, ou utiliser des bibliothèques qui s'appuient sur ces fonctionnalités, si vous avez besoin de votre source pour compiler sur d'autres compilateurs C++. Vérifiez d'abord le tableau de compatibilité .

Une autre chose est endianess . Juste un exemple, lorsque vous écrivez un flux d'entiers à déposer sur une plate-forme (par exemple, x86 ou x86_64), puis que vous le relisez sur une autre plate-forme (par exemple, POWER), vous pouvez rencontrer des problèmes. Pourquoi écririez-vous des entiers dans un fichier? Eh bien, UTF-16 est entiers ... encore une fois, la discipline et une certaine expérience contribuent grandement à rendre cela plutôt indolore.

Une fois que vous avez coché toutes les cases celles-ci, vous devez vous assurer de la disponibilité des bibliothèques sur lesquelles vous basez votre code sur. Tandis que std:: est sûr (mais voir "tous les compilateurs ne sont pas créés égaux" ci-dessus), quelque chose d'aussi innocent que boost:: peut devenir un problème si vous regardez au-delà du courant dominant. (J'ai aidé les gars de Boost à corriger un ou deux showstoppers concernant AIX/Visual Age ces dernières années simplement parce qu'ils n'avaient pas accès à cette plateforme pour tester les nouvelles versions ...)

Oh, et faites attention aux différents régimes de licences qui existent. Certains cadres qui améliorent vos capacités multiplateformes - comme Qt ou Cygwin - ont leurs chaînes attachées. Cela ne veut pas dire qu'ils ne sont pas d'une grande aide dans les bonnes circonstances, juste que vous devez être conscient des exigences de licence copyleft/propriétaire.


Cela étant dit, il y a Wine ("Wine n'est pas une émulation"), ce qui rend les exécutables compilés pour Windows run on une variété de systèmes semblables à Unix (Linux, OS X, * BSD, Solaris). Il y a certaines limites à ses capacités, mais ça s'améliore tout le temps.

18
DevSolar

Oui. Non peut-être. Qu'est-ce que le code C++ multiplateforme? Le code C++ multiplateforme est un tel code qui peut être compilé sous différents systèmes d'exploitation sans avoir besoin d'être modifié.

Cela signifie que si vous utilisez explicitement des en-têtes dépendant de la plate-forme, votre code n'est plus multiplateforme. Qt résout ce problème de la manière suivante: ils fournissent des wrappers pour tout ce qui est spécifique à la plate-forme. Par exemple, imaginez que vous utilisez QFile pour ouvrir/lire/écrire un fichier. Votre code ressemble à

QFile file(filename);
file.open(QFile::ReadOnly);
//other stuff

Vous pouvez compiler ce code sous n'importe quel système d'exploitation tant que vous disposez d'un compilateur approprié et de bibliothèques Qt pour ce système d'exploitation. Le code caché sous QFile utilisera les fonctions de gestion de fichiers adaptées au système d'exploitation, mais cela ne devrait pas vous concerner.

De plus, si vous utilisez uniquement la bibliothèque standard, votre code peut être compilé partout où un compilateur C++ est présent.

Les applications déjà compilées, cependant, ne sont pas multiplateformes d'une manière qui, par exemple, Java sont - par exemple, vous ne pouvez pas compiler une application pour Windows, puis l'exécuter dans Linux, vous devrez recompiler votre code sous Linux à la place.

6
SingerOfTheFall

C++ est un langage de programmation. Texte. En tant que tel, il ne fonctionne nulle part.

Le code C++ standard conforme devrait se comporter également sur n'importe quelle plate-forme; "multiplateforme" si vous le souhaitez. L'écriture de code C++ (strictement) conforme nécessite un pédantisme car certaines hypothèses souvent faites ont des dépendances sur les détails qui sont finales pour l'implémentation réelle et cela est hérité des cibles que C++ lui-même vise.

Notez que nous parlons toujours de code C++, pas de programmes C++. En effet, lorsque nous passons au terme "programme", nous n'avons plus de garanties car nous ne parlons plus de C++; plutôt, la sortie du compilateur. C'est là que la portabilité commence à s'estomper: format exécutable, ISA, ABI, routines de bas niveau, etc.
Pouvez-vous compter sur cela? Si vous ne le pouvez pas, vous devez intégrer votre programme C++ dans l'environnement sur lequel il s'exécutera, en le recompilant ou en utilisant des éléments spécifiques à la plate-forme.

4
edmz

C++ est multiplateforme. Vous pouvez l'utiliser pour créer des applications qui s'exécuteront sur de nombreux systèmes d'exploitation différents.

Ce qui n'est pas multiplateforme, ce sont les compilateurs qui traduisent C++ en code objet. Aucun compilateur unique, à ma connaissance, ne possède toutes les fonctionnalités nécessaires pour que lorsque vous l'utilisez pour compiler un programme C++, il s'exécute automatiquement sur Windows, Linux et Mac OS.

Qt Creator est intégré à plusieurs compilateurs et dispose d'une automatisation de génération. Il permet de basculer facilement entre différentes configurations et plates-formes cibles. Il prend en charge la création, l'exécution et le déploiement d'applications C++ non seulement pour les environnements de bureau mais également pour les appareils mobiles.

3
dspfnder