c + + - Kan jeg oprette en funktion baseret på en anden funktion ved kørsel?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg spiller med Microsofts omkørsler til at hænge api, for eksempel kan jeg ændre, hvad der sker, når MessageBoxA
kaldes på denne måde: [13]


  int (WINAPI* pMessageBoxA)(HWND, LPCTSTR, LPCTSTR, UINT) = MessageBoxA;

  int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
  {
      printf("A function is called here!
");
      return pMessageBoxA(hWnd, lpText, lpCaption, uType);  // call the regular MessageBoxA
  }

  DetourTransactionBegin();
  DetourUpdateThread(GetCurrentThread());
  DetourAttach(&(PVOID&)pMessageBoxA, MyMessageBoxA); 


Så når du ringer til MessageBoxA, ringer du faktisk MyMessageBoxA.

Nu vil jeg skrive en funktion Hook(), som ville gøre, hvad koder ovenfor gør ved runtime. Hvis jeg for eksempel overgiver funktionspegeren MessageBoxA til funktionen, vil den gøre præcis hvad den ovennævnte kode gjorde.

Selvfølgelig kan jeg også sende en anden funktionspeger til det.

Så kan jeg definere en funktion med samme returværdi og parameter som den givne funktion (i dette tilfælde MessageBoxA til int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType), når jeg får en funktionspeger i Hook]]) og derefter udfylde funktionens funktionskrop?

Bedste reference


I C ++ er funktionerne ikke første klasse objekt, det vil sige, at de ikke kan oprettes ved kørsel. [14]


Du kan dog bruge en række funktionspegere, hver peger peger på en allerede defineret funktion og vælger den relevante funktionspeger ved kørsel på basis af nogle betingelser og kalder det. Og det ser ud til at du allerede bruger funktion-pointer i kodestykket.

Andre referencer 1


Det er ikke helt sandt. Du kan nemt gemme en (medlem) funktionsreference, så du kan få en funktion til at ringe til en anden funktion (bestemmer ved kørselstid).


Du kan også bruge en functor, som er en struktur/klasse olverloading () operatøren. Dette kan så bruge klassens tilstand til at huske hvilken faktisk funktion at ringe. Et eksempel på en functor:


STL har en <functional> header, der indeholder en masse nyttige værktøjer til at gøre handling (medlem) funktion referencer 'lettere' (lidt). Tilfældigt eksempel fra cplusplus.com:[15]


// mem\_fun example
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

int main () 
{
  vector <string*> numbers;

  // populate vector of pointers:
  numbers.push\_back ( new string ("one") );
  numbers.push\_back ( new string ("two") );
  numbers.push\_back ( new string ("three") );
  numbers.push\_back ( new string ("four") );
  numbers.push\_back ( new string ("five") );

  vector <int> lengths ( numbers.size() );

  transform (numbers.begin(), numbers.end(), lengths.begin(), mem\_fun(&string::length));

  for (int i=0; i<5; i++) {
      cout << *numbers[i] << " has " << lengths[i] << " letters.
";
  }
  return 0;
}


c ++ 0x har mange nifty nye funktioner (herunder 'auto' type inference og lambda udtryk), der vil gøre meget af dette lettere