2011-06-16 4 views
1

Je suis en train d'écrire un jeu et pour l'instant j'ai pu implémenter un système de fichiers via sqlite avec une classe et ses méthodes. Pour rendre la vie plus facile j'ai prévu d'écrire certaines fonctions comme fopen, fclose, fread, rename, etc. pour pouvoir occulter les fonctions de base et diriger mes appels vers mon système de fichiers plutôt que vers l'original. Pour la première tout fonction de trois a bien fonctionné pour moi avec ces prototypes:Fonctions d'observation de C stdlib/stdio

File *fopen(String _Filename, String _Mode); // i have my own optimized File struct

void fclose(File *_File);

size_t fread(String *_DstBuf, size_t _ElementSize, size_t _Count, File *_File);

Cela a bien fonctionné comme je suis soit retournais une autre struct ou les paramètres à l'exception d'un File* et non d'un FILE*, cependant la fonction renommer semble être un peu plus compliquée!

int rename(String _OldFilename, String _NewFilename);

Ceci est à peu près le même prototype. sauf que j'utilise std::string (typedef'ed String) que const char*! Une idée de comment je pourrais convaincre mon compilateur d'utiliser ma fonction ou d'ignorer le stdio-one?

Répondre

5

Et quelle est la raison pour laquelle vous ne pouvez pas simplement utiliser vos propres fonctions par un autre nom? Si le conflit entier est avec la résolution de surcharge, vous devez simplement simplement ombrer les réels prototypes; Vous pouvez les faire avancer vers vos propres fonctions.

Cependant, je déconseille l'approche générale ici: même avec cette 'solution' en place, vous aurez au mieux des problèmes de commande, et peut-être même des symboles de lien en double.

Si vos fonctions ne font pas la même chose, utilisez un autre nom. Puisque vous utilisez C++, vous pouvez faire ce truc immonde (autrement malavisée) dans MyFsFunctions.h:

namespace MyFsFunctions 
{ 
    // prototypes for fopen, fclose, fwrite, fread etc 
} 

using namespace MyFsFunctions; 
// or: 
using MyFsFunctions::fopen; 
using MyFsFunctions::fclose; 
using MyFsFunctions::fread; 
using MyFsFunctions::fwrite; // etc... 

Je suis sûr que vous voulez toujours (besoin) à l'ombre des prototypes exactes de fonction (ou le compilateur peut encore se plaindre de références d'identifiants ambiguës).

Autres conseils:

  1. utiliser un pilote de système de fichiers FUSE (sous Linux/UNIX/MacOS, peut-être exagéré, mais sa mise en œuvre semble beaucoup plus robuste et peut encore plus simple que ce que vous faites ici).
  2. il y a toujours des macros C (-10 points pour le mal)
  3. éditeur de liens gnu a des options qui vous permet de « remplacer » symboles de lien - principalement à des fins de débogage, mais vous pouvez tirer parti de ceux qui sont ici
+0

L'astuce de l'espace de noms vil fonctionnait bien pour les premiers prototypes, mais j'ai le problème avec 'rename' car le compilateur n'est pas capable de décider si mes params sont' const char * 'ou' String's! Essayer d'appeler 'renommer (String ("/dev/null "), String ("/dev/less "));' résoudre le conflit, mais il n'est pas bon d'appeler le constructeur 'String' chaque fois que je passe un argument . –

+1

Pourriez-vous essayer d'ajouter explicitement 'using MyFsFunctions :: rename;' en plus de/à la place de 'using namespace MyFsFunctions;'? – sehe

+1

Ne fonctionne pas! Cependant, un '#define rename MyFsFunctions :: rename' pourrait résoudre le problème, mais c'est C++ et je n'aime pas les macros comme dans C>.

3

Que diriez-vous d'implémenter un rename avec la signature standard que tout ce qu'il fera serait d'appeler votre String ed version?

Cela ne me semble pas compliqué. Quelque chose comme ceci:

int rename(const char *charOld, const char *charNew) 
{ 
    std::string stdOld(charOld); 
    std::string stdNew(charNew); 
    return rename(stdOld, stdNew); 
} 
+1

Ouais, et faites-le 'inline' ... – vines

+0

@vines - bon point – littleadv

+0

@littleadv et @vines - n'a pas fonctionné! le compilateur l'a simplement ignoré! –