2011-06-16 2 views
1

Я пишу игру, и на данный момент я смог реализовать файловую систему через sqlite с классом и его методами. Чтобы облегчить жизнь, я планировал написать некоторые функции, такие как fopen, fclose, fread, rename и т. Д., Чтобы иметь возможность затенять базовые функции и направлять мои вызовы на мою файловую систему, а не на исходную. Для первых три функций все работало нормально для меня с этими прототипами:Теневые функции 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);

Это работало нормально, как я либо возвращая структуру или параметры кроме File*, а не FILE*, однако функция переименования кажется немного сложнее!

int rename(String _OldFilename, String _NewFilename);

Это почти тот же прототип. за исключением того, что я использую std::string (typedef'ed String), чем const char*! Любая идея, как я могу убедить мой компилятор использовать мою функцию или игнорировать stdio-one?

ответ

5

И в чем причина, почему вы не можете просто использовать свои собственные функции любым другим именем?

Если весь конфликт с разрешением перегрузки, вы просто должны просто скрыть прототипы; Вы можете перевести их на свои собственные функции.

Тем не менее, я рекомендую использовать общий подход здесь: даже с этим «исправлением» на месте вы, в лучшем случае, имеете проблемы с упорядочением и, возможно, даже дублируете символы ссылок.

Если ваши функции не делают то же самое, заставьте их использовать другое имя. Так как вы используете C++, вы могли бы сделать эту мерзкую выходку (иначе опрометчивого) в 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... 

Я уверен, что вы все еще хотите (потребность) в теневое точные прототипы функций (или компилятор все равно может жаловаться на ссылки неоднозначных идентификаторов).

Другие советы:

  1. использовать драйвер запал файловой системы (на Linux/UNIX/MacOS, может быть излишним, но реализация его кажется намного более надежным и может даже проще, чем то, что вы делаете здесь).
  2. всегда есть C макросы (-10 баллов за зло)
  3. гну линкер имеет опции, давайте вы «заменить» ссылка символы - в основном для целей отладки, но вы можете использовать те здесь
+0

Простой трюк пространства имен работал отлично для первых прототипов, однако у меня проблема с 'rename', поскольку компилятор не может решить, являются ли мои параметры' const char * 'или' String '! Попытка называть 'rename (String ("/dev/null "), String ("/dev/less "));' разрешил конфликт, однако не всегда полезно вызывать конструктор 'String' каждый раз, когда я передаю аргумент , –

+1

Не могли бы вы явно добавить 'using MyFsFunctions :: rename; 'в дополнение к/вместо' using namespace MyFsFunctions; '? – sehe

+1

Не работает! Однако '#define переименовать MyFsFunctions :: rename' может решить проблему, но это C++, и я не люблю макросы, как в C>.

3

Как насчет внедрения rename со стандартной подписью, что все, что он сделает, будет вызывать вашу String версию ed?

Не кажется мне сложным. Что-то вроде этого:

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

Да, и сделайте это 'inline' ... – vines

+0

@vines - хорошая точка – littleadv

+0

@littleadv и @vines - не сработало! компилятор просто проигнорировал это! –