Because a certain member of the forums (*cough* typedef *cough*) is a retard (apparently me using typdef on functions pointers is impossible and means I must have "shit for brains" -- his words) I figured other people must suffer from the same misconception so I will explain how to use a typedef with functions or function pointers.
Note: These are all REAL WORLD examples from one of my projects, so typedef (the person) can't go "ZOMG THIS NO WORK" because I'm using it right now and it does.
Functions:
When writing a callback system for my console I needed choose a function prototype all the callbacks would follow, I chose the following:
In order to make writing the callback system easier on myself I used 'typedef' to create a type synonym for the callback prototype:Code:void __cdecl CallbackName(const std::string& Params);
I could then use the type "ConsoleCallback" instead of typing out the ugly type definition I would have to otherwise. An important thing to note is typedef defines a TYPE SYNONYM, meaning the word actually is a type, it is NOT a 'define' that just copy-pastes using the preprocessor before the compiler takes over, the compiler sees "ConsoleCallback" as a type and treats it as such.Code:typedef void (__cdecl ConsoleCallback) (const std::string &);
You can then use the new type synonym as such:
std::map<std::string,ConsoleCallback*> ConsoleCallbacks;
Code:void __cdecl TestCallback(const std::string&) { ; } void RegisterConsoleCallback(const std::string& Name, ConsoleCallback* Callback) { ConsoleCallbacks[Name] = Callback; } void RegisterCallbacks() { RegisterConsoleCallback("test",&TestCallback); } std::string Submit( const char * /*pszArgs*/, CElement * pThis ) { std::string sString(pThis->GetString()); string Command = sString.substr(0, sString.find(" ")); string Args = sString.substr(sString.find(" ")+1,sString.size()); std::transform(Command.begin(), Command.end(), Command.begin(), tolower); if (ConsoleCallbacks[Command]) { ConsoleCallback* pMyCallback = ConsoleCallbacks[Command]; (*pMyCallback)(Args); } else { WriteOutput("Invalid command."); } pThis->SetString(""); return std::string(); }
Function Pointers:
Typedefs are also useful when calling game function from an injected DLL in the form of a function pointer, this is great because you can avoid the use of inline ASM and have the compiler take care of the stack for you (and generate 'better' ASM because there are no __asm blocks that hinder the compiler's optimizer).
Example (from my fishbot, modified, unrelated code removed):
You can then use the code to cast for example 'Fishing (Apprentice)' which has ID 7620.Code:typedef bool (__cdecl * tCastSpellById)(unsigned int SpellId, unsigned int Unk2, unsigned int Unk3, unsigned int Unk4); tCastSpellById oCastSpellById = 0; void SetupMiscFunctions() { oCastSpellById = (tCastSpellById)GetRPMgr()->GetFindPattern()->GetAddress("CSpell::CastSpellById"); } void CastSpell(unsigned int SpellId) { oCastSpellById(SpellId,0,0,0); }
Hopefully now everyone can see you CAN use 'typedef' to define function and function pointer type synonyms.