I am writing a game and for now i was able to implement a filesystem via sqlite
with a class and its methods. To make life more easy i have planned to write some functions like fopen
,fclose
,fread
,rename
, etc. to be able to shadow the base functions and to direct my calls to my filesystem rather than to the original one. For the first three function everything worked fine for me with these prototypes:
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);
This worked fine as i am either returning anoth开发者_StackOverflow中文版er struct or the parameters except a File*
and not a FILE*
, however the rename function seems to be a bit trickier!
int rename(String _OldFilename, String _NewFilename);
This is nearly the same prototype. except that i use std::string
(typedef'ed String
) than const char*
! Any idea how i could convince my compiler either to use my function or to ignore the stdio-one?
And what is the reason that you cannot simply use your own functions by any other name?
If the whole conflict is with overload resolution, you should simply just shadow the actual prototypes; You can make them forwards to your own functions.
However, I recommend against the general approach here: even with that 'fix' in place you will at the very best have include ordering issues, and possibly even duplicate link symbols.
If your functions don't do the same, make them use another name. Since you are using c++, you could do this vile trick (otherwise ill-advised) in 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...
I'm pretty sure you will still want (need) to shadow the exact function prototypes (or the compiler may still complain about ambiguous identifiers references).
Other hints:
- use a fuse file system driver (on Linux/UNIX/MacOS; might be overkill, but implementing it seems a lot more robust and may even simpler than what you do here).
- there is always C macros (-10 points for evil)
- gnu linker has options that let's you 'replace' link symbols - mainly for debugging purposes, but you can leverage those here
How about implementing a rename
with the standard signature that all it will do would be calling your String
ed version?
Doesn't sound complicated to me. Something like this:
int rename(const char *charOld, const char *charNew)
{
std::string stdOld(charOld);
std::string stdNew(charNew);
return rename(stdOld, stdNew);
}
精彩评论