Ich stelle mich vielleicht nur wieder zu dumm beim Druchsuchen der Manuals und dieses Forums an, fand jedoch die Antwort bisher nicht: Ich möchte eine Funtion in Assembler schreiben und von einem Cpp-Programm aus aufrufen: *.S-File: .global wait .func wait wait: // Assembler-Anweisungen *.cpp-File: void wait(void); int main() { wait(); } Dieses geht schief, weil avr-gcc offenbar aus 'void wait(void)' den Namen '_Z4waitv' generiert. (Habe durch Versuche herausgefunden, dass immer '_Z + Anzahl der Buchstaben des Namens + Name + v' erzeugt wird.) Wenn ich in meinem *.S-File diesen kryptischen Namen einsetze, geht es. Wie kann ich erreichen, in meinem *.S-File nicht mit so kryptischen Namen hantieren zu müssen? Gruß, Michael
Hallo Michael. In meine Assemblerdatei (.S) schreibe ich: .section .text .global uuprintf_P .type uuprintf_P, @function uuprintf_P: ... Das ganze wird mit: avr-gcc -Os -g3 -mmcu=atmega8 -Wa,-gstabs -c uuprintf.S /bin/sh ../libtool --mode=link --tag=CC avr-gcc -Os -g3 -mmcu=atmega8 -Wa,-gstabs -o avrthermometer2 avrthermometer2.o sensor.o asmfkt.o lcd.o mprintf.o uuprintf.o unter KDevelop übersetzt. In avrthermometer2.c steht u.a: const char pstr1[] PROGMEM = "Temp = %\000C "; extern void uuprintf_P(char *s, const char *ff, uint16_t n); ... int main(void) { ... char A[20]; uuprintf_P(A, pstr1, (uint16_t) ScratchPad[0]>>1); ... } und alles funktioniert ohne _Zxyv. Vielleicht hilft es. Gruß Marco -
> Dieses geht schief, weil avr-gcc offenbar aus 'void wait(void)' den > Namen '_Z4waitv' generiert. (Habe durch Versuche herausgefunden, > dass immer '_Z + Anzahl der Buchstaben des Namens + Name + v' > erzeugt wird.) Dafür brauchst du genau genommen keine Versuche, sondern nur die Doku: http://www.codesourcery.com/cxx-abi/abi.html#mangling Aber zugegeben, diese Doku ist nichts, was man so nebenbei mal überfliegt, und meistens muss man das so genau gar nicht kennen. Wie so häufig gilt auch hier: Wichtig ist zu wissen, dass es so etwas gibt, nicht wie genau es funktioniert (grobe Implementierungskenntnisse können aber nie schaden). Mit "so etwas" meine ich das "name mangling", eine Eigenart von C++. C++ unterstützt Überladung und namespaces. Beides bewirkt, dass Funktionen mit ein und demselben Namen mehrmals existieren können. Damit da nichts kollidiert, hat man zwei Möglichkeiten: 1. Den Linker und das Format der kompilierten Zwischendateien anpassen. 2. Die ganzen zusätzlichen Infos in die Funktions- und Klassennamen kodieren und den gewöhnlichen C-Linker nehmen. Man hat sich für zweitens entschieden. Deswegen wird aus "void wait()" ein "_Z4waitv", damit z.B. gleichzeitig eine Funktion "void wait(int)" existieren kann (letzteres würde zu "_Z4waiti" werden). Für einzelne Funktionen kann man das deaktivieren, indem man extern "C" davor schreibt: extern "C" void wait(); Dann wird der Funktionsname nicht dekoriert, allerdings kann man die Funktion (logischerweise) nicht mehr überladen.
Schreibe im *.cpp-File: #ifdef __cplusplus extern "C" { void wait(void); } #endif
Vielen Dank Euch allen! @Christoph: Super Erklärung, jetzt versteh' ich, was dahinter steckt. Wenn ich das File als *.c speichere und compiliere, tritt das Ganze (logischer Weise) nicht auf. @Marco S: Danke auch Dir, wie schon erwähnt, ist es ein reiner C++-Effekt, der bei Dir daher nicht auftritt. @Roland Schmidt: Durchaus nicht zu langsam! Du hast mir gezeigt, wie man das 'extern "C"' für mehrere Funktionen kürzer schreiben kann, also auch Dir vielen Dank! Gruß, Michael
> Schreibe im *.cpp-File: > > #ifdef __cplusplus > extern "C" { > > void wait(void); > > } > #endif Komplett wäre es so: #ifdef __cplusplus extern "C" { #endif void wait(void); #ifdef __cplusplus } #endif Denn die Deklaration soll ja auch dann vorhanden sein, wenn man das als C compiliert. Es soll nur nicht in einem extern "C" block stehen.
Vielen Dank auch für diesen Hinweis. Das wäre bei mir wahrscheinlich nie aufgefallen, da ich immer *.cpp-Files habe und alles als C++ compiliere. Gruß, Michael
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.