Теневые функции C stdlib / stdio - PullRequest
1 голос
/ 16 июня 2011

Я пишу игру, и на данный момент я смог реализовать файловую систему через sqlite с классом и его методами.Чтобы упростить жизнь, я запланировал написать некоторые функции, такие как fopen, fclose, fread, rename и т. Д., Чтобы иметь возможность скрывать базовые функции и направлять свои вызовы в мою файловую систему, а не воригинальный.Для первых трех функций у меня все работало нормально с этими прототипами:

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?

Ответы [ 2 ]

5 голосов
/ 16 июня 2011

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

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

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

Если ваши функции не выполняют то же самое, заставьте их использовать другое имя. Так как вы используете 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. используйте драйвер файловой системы fuse (в Linux / UNIX / MacOS; может быть, это излишне, но его реализация кажется намного более надежной и может быть даже проще, чем то, что вы здесь делаете).
  2. всегда есть макросы C (-10 очков за зло)
  3. В компоновщике GNU есть опции, которые позволяют вам «заменять» символы ссылок - в основном для целей отладки, но вы можете использовать их здесь
3 голосов
/ 16 июня 2011

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

Мне не кажется сложным.Как то так:

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