Hi, die eingebaute printf-Funktion des gcc ist riesig (~30k), deshalb benutze ich schon eine Weile eine Kleinere*. Angenommen ich habe eine printf-Funktion, die "my_printf" benannt ist. Nun möchte ich eine Wrapper-Funktion schreiben, die "printf" benannt ist. Ich möchte nun printf, sprintf und snprintf der library übergehen, jedoch nicht die ganze library abschalten (z.B. strlen will ich behalten). Wie kann ich das bewerkstelligen? *hier ein paar Implementationen: https://github.com/cjlano/tinyprintf https://github.com/trini/u-boot/blob/master/lib/tiny-printf.c https://github.com/mpaland/printf http://www.xappsoftware.com/wordpress/2011/01/17/a-tiny-printf-for-embedded-systems/ http://www.firefly-power.de/ARM/printf.html
Das Stichwort dürfte hier "weak linkage" heißen. Damit kann man eine in einer Library verwendete Funktion durch eine andere ersetzen, ohne auf die Library verzichten zu müssen. Voraussetzung ist, daß "printf" in Deiner Standardlibrary als "weak symbol" definiert ist, das musst Du also gegebenenfalls anpassen. http://www.valvers.com/programming/c/gcc-weak-function-attributes/
Einfach die neue printf in eine Datei packen und mitlinken reicht aus. Die Version aus der libc wird nur genommen, wenn keine andere vorhanden ist.
Das weak linkage, was Rufus schrieb, wird bei mir der Fall sein. Denn, wenn ich es so mache, wie foobar schrieb, wird mein printf-wrapper verwendet. Wenn die library-Funktion nicht "weak" ist, dann bekomme ich mit diesem Code eine Fehlermeldung a la "already defined", oder? Vielen Dank für den Denkanstoss, das hat mir schon einiges an Kopfzerbrechen bereitet.
Safari schrieb: > Wenn die library-Funktion nicht "weak" ist, dann bekomme ich mit diesem > Code eine Fehlermeldung a la "already defined", oder? Nein. Der Linker holt beim Linken nur die Symbole aus einer Library, die er zu dem Zeitpunkt (die Reihenfolge in der Kommandozeile spielt da eine Rolle) noch nicht resolved hat. Wenn Du ihm also früher schon (in einer Objektdatei, z.B.) ein passendes Symbol anbietest, sucht in in der Library gar nicht erst danach. "Weak"-Symbole braucht man eigentlich nur (dynamisches Linken, das bei der µC-Programmierung keine Rolle spielt, mal aussen vorgelassen), wenn man eine Default-Implementierung anbieten, aber dem Anwender eine Möglichkeit geben will, seine eigene Spezialisierung mitzubringen bzw. den Default zu überschreiben (wie z.B. im Startup-Code).
Das mit dem "weak-linkage" ist, wie GNU das typische Verhalten implementiert und erweitert hat. Wenn der Linker nen Symbol sucht, nimmt er die erste Definition, die er findet. Dabei wird nicht nur ein Symbol, sondern das gesamte o-File dazugelinkt, in dem das Symbol gefunden wurde. Definiert ein o-File mehrere Symbole, kann es zu dem "double-defined"-Fehler kommen[1]. Die herkömmliche Lösung ist, jedes exportierte Symbol in ein eigenes o-File zu packen (d.h. ein File für strlen, eins für strcpy, eins für strncpy, etc). Mit dem weak/strong Attribut hat GNU das Linken erweitert, indem es jedem Symbol noch ne Priorität mitgibt. Die Symbole in normalen c-Files sind strong, die in Libraries typischerweise weak. Kommen dann ein strong und ein oder mehrere weak-Symbole zusammen, gibt es keine Fehlermeldung mehr, sondern das strong gewinnt. D.h. aber nicht, dass nicht beide Versionen im Programm vorhanden sind, es wird halt nur die strong Version benutzt (neuere Linker können unter bestimmten Umständen unbenutzte Funktionen wegoptimieren, das ist aber ne weitere GNU-Extension). Normalerweise braucht man sich darum nicht zu kümmern - es klappt einfach. Wenn die double-defined Meldung kommt, stimmt normalerweise in deinem Programm was nicht und sollte genauer untersucht werden. [1] Beispiel: strcpy und strncpy sind in einem .o-File im clib. Du definierst dir dein eigenes strncpy, das explizit mitgelinkt wird (in z.b. mystrncpy.o). Wenn dein Programm nun strcpy (ohne n) benutzt, holt der Linker das aus dem clib, leider zusammen mit dem clib-strncpy, das ja im gleichen File ist. Peng, double defined strncpy.
Vielen Dank für die ausführlichen Erklärungen. Nun kann ich ruhigen Gewissens diverse Funktionen ersetzen und weiss um das Verhalten des Linkers.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.