L'écriture de la croix-plate-forme de Code C++ (Windows, Linux et Mac OSX)
C'est ma première tentative à écrire n'importe quoi, même un peu compliqué en C++, je suis d'essayer de construire une bibliothèque partagée que je peut s'interfacer avec d'Objective-C, et .NET applications (ok, ça vient plus tard...)
Le code que j'ai est -
#ifdef TARGET_OS_MAC
//Mac Includes Here
#endif
#ifdef __linux__
//Linux Includes Here
#error Can't be compiled on Linux yet
#endif
#ifdef _WIN32 || _WIN64
//Windows Includes Here
#error Can't be compiled on Windows yet
#endif
#include <iostream>
using namespace std;
bool probe(){
#ifdef TARGET_OS_MAC
return probe_macosx();
#endif
#ifdef __linux__
return probe_linux();
#endif
#ifdef _WIN32 || _WIN64
return probe_win();
#endif
}
bool probe_win(){
//Windows Probe Code Here
return true;
}
int main(){
return 1;
}
J'ai un avertissement du compilateur, il suffit de untitled: In function ‘bool probe()’:untitled:29: warning: control reaches end of non-void function
- mais j'ai aussi vraiment apprécier toutes les informations ou ressources que l'on peut suggérer pour savoir comment écrire ce genre de code mieux....
Vous devez vous connecter pour publier un commentaire.
Je vais répondre à cette fonction spécifique:
Écrit de cette façon, comme une chaîne de si-elif-sinon, élimine l'erreur, car il est impossible de compiler sans retour valable déclaration ou de frapper la #erreur.
(Je crois WIN32 est défini pour les deux 32 - et 64-bit de Windows, mais je ne pourrais pas vous dire de manière définitive sans regarder. Qui permettrait de simplifier le code.)
Malheureusement, vous ne pouvez pas utiliser des #ifdef _WIN32 || _WIN64: voir http://codepad.org/3PArXCxo pour un exemple de message d'erreur. Vous pouvez utiliser le prétraitement seule défini opérateur, comme je l'ai fait ci-dessus.
Concernant le fractionnement des plates-formes selon les fonctions ou ensemble de fichiers (comme suggéré), vous pouvez ou ne voulez pas le faire. Ça va dépendre des détails de votre code, telles que combien est partagé entre les plates-formes et ce que vous (ou votre équipe) trouver mieux pour garder la fonctionnalité de synchronisation, entre autres questions.
En outre, vous devez gérer sélection de plate-forme dans votre système de construction, mais cela ne signifie pas que vous ne pouvez pas utiliser le préprocesseur: utiliser des macros conditionnelle définies (par le makefile ou système de construction) pour chaque plate-forme. En fait, c'est souvent la solution la plus pratique avec des modèles et des fonctions inline, ce qui le rend plus flexible que d'essayer d'éliminer le préprocesseur. Il se marie bien avec l'ensemble du fichier d'approche, de sorte que vous utilisez encore que, le cas échéant.
Vous pouvez avoir une seule config en-tête qui traduit tous les différents compilateur de la plate - forme et des macros spécifiques dans le bien-connu et compris les macros que vous avez le contrôle. Ou vous pouvez ajouter -DBEAKS_PLAT_LINUX à votre compilateur de ligne de commande—par le biais de votre système de construction,—de définir cette macro (n'oubliez pas d'utiliser un préfixe pour les noms de macro).
au lieu de se répéter et écrire le même #ifdef .... lignes, encore, encore et encore, vous êtes peut-être mieux de déclarer la sonde() dans un en-tête, et de fournir des trois fichiers sources différents, un pour chaque plate-forme. Cela a aussi l'avantage que si vous ajoutez une plate-forme, vous n'avez pas à modifier l'ensemble de vos sources existantes, mais seulement ajouter de nouveaux fichiers. Utilisez votre système de construction pour sélectionner le fichier source.
Structure exemple:
L'avertissement est à cause de la sonde() ne retourne pas une valeur. En d'autres termes, aucun des trois #ifdefs matchs.
Il semble qu'aucun de
TARGET_OS_MAC
,__linux__
,_WIN32
ou_WIN64
est défini au moment de la compilation du code.Si c'est comme votre code est:
C'est pourquoi le compilateur se plaint d'atteindre la fin de non-void function. Il n'y a pas de
return
clause.Aussi, pour la question plus générale, ici sont mes lignes directrices dans le développement multi-plate-forme/architecture logiciel/bibliothèques:
Éviter des cas spécifiques. Essayez d'écrire du code qui est OS-agnostique.
Lorsque vous traitez avec système spécifique des choses, essayez d'envelopper les choses en "opaque" des classes. Par exemple, si vous travaillez avec des fichiers (Api différentes sur Linux et Windows), essayez de créer un
File
classe qui va intégrer la logique et de fournir une interface commune, quel que soit le système d'exploitation. Si certaines fonctionnalité n'est pas disponible sur l'un des OS, traiter avec elle: si la fonction n'a pas de sens pour un système d'exploitation spécifique, il est souvent fine de ne rien faire du tout.En bref: moins
#ifdef
le mieux. Et n'importe comment portable votre code, de le tester sur chaque plate-forme avant de le relâcher.Bonne chance 😉
right
répondre à quelqu'un qui m'a aidé sur IRC (Roger), mais que de bons conseils, comme toujours.L'avertissement est que si aucun définit sont en fait définis alors vous n'avez aucune
return
dans votre sonde de fonction. Le correctif de ce qui est mis en défautreturn
.À ajouter quelque chose en plus de cela, d'autres que les options en circulation au-dessus, les directives
__linux__
et_WIN32
sont connus pour le compilateur, où laTARGET_OS_MAC
la directive n'a pas été, cela peut être résolu en utilisant__APPLE__
. Source: http://www.winehq.org/pipermail/wine-patches/2003-July/006906.html