Das System muss so konzipiert sein, dass dies funktioniert.
Es gibt verschiedene Aspekte, die koordiniert werden müssen:
- Es muss eine Möglichkeit geben, die Funktionszeiger zu ändern.
- Der Code muss die Funktionen über die Zeiger aufrufen.
Es gibt mehrere Möglichkeiten, dies im Detail zu tun, aber sie sind letztlich nur Varianten eines Themas.
/* Declaration of function pointer used to invoke the function */
extern int (*filename_func_ptr)(int arg1, char const *arg2);
/* Two versions of the function */
extern int filename_func_1_1(int arg1, char const *arg2);
extern int filename_func_1_2(int arg1, char const *arg2);
/* Definition of function pointer - pointing to version 1.1 of the function */
int (*filename_func_ptr)(int arg1, char const *arg2) = filename_func_1_1;
/* Use of function pointer */
static void some_function(void)
{
printf("%d\n", (*filename_func_ptr)(1, "pi"));
}
Beachten Sie, dass Sie möglicherweise nie beides haben filename_func_1_1()
y filename_func_1_2()
in derselben Datei deklariert. Der Effekt, den ich beschreibe, ist "als ob".
Nach Parcheando, mit welchen Mitteln auch immer, ist das Ergebnis so, als hätten Sie das geschrieben:
int (*filename_func_ptr)(int arg1, char const *arg2) = filename_func_1_2;
Sie können Probleme mit dem dynamischen Laden bekommen ( dlsym()
sowie dlopen()
usw.), um die neuen Symbole zu erhalten. Das würde einen Dateinamen für die Bibliothek benötigen, um dynamisch zu laden, sowie eine Möglichkeit, die Funktionsnamen in Zeiger auf die richtigen Funktionen zu konvertieren.
Jede patchbare Funktion muss gleichmäßig über den Zeiger aufgerufen werden. Dies ermöglicht es Ihnen, die Funktion zu ersetzen. Überlegen Sie, ob eine dynamische (gemeinsam genutzte) Bibliothek ausreicht (weil sie wahrscheinlich einfacher ist). Wenn Sie mit Firmware arbeiten, können Sie sich diesen Luxus wahrscheinlich nicht leisten.
Sie müssen sich überlegen, wie Sie mehrere Funktionen mit unterschiedlichen Schnittstellen handhaben; werden Sie einzelne globale Variablen verwenden, wie hier gezeigt, oder einen generischen Funktionszeigertyp, der bei jedem Aufruf entsprechend gecastet werden muss, oder einen Unionstyp, oder eine Struktur, die Zeiger enthält, oder ...? Es gibt viele Möglichkeiten, die Dinge zu organisieren.