Hallo an alle, ich habe folgendes Problem: am Ende muss in meinem Code sowas sein: close_gpio ("27"); ich möchte nun über den Präprozessor die 27 ausrechen lassen und dort einfügen lassen. Also: #define GPIO_TO_PIN(bank,gpio) (32 * (bank) + (gpio)) Das hier geht natürlich nicht....: close_gpio("GPIO_TO_PIN(0,27)") Wie kann man sowas machen bzw. geht sowas überhaupt?
Hi Mach mal die Anführungszeichen weg vlt. geahts dann.
Testi schrieb: > am Ende muss in meinem Code sowas sein: > > close_gpio ("27"); Ganz sicher, daß das ein String sein soll?
Testi schrieb: > geht sowas überhaupt? Der C-Präprozessor kann zwar Integer-Ausdrücke auswerten, aber nur in der Bedingung von #if-Direktiven, nicht aber bei der Makroexpansion. Deswegen ist die Antwort erst einmal nein. Man kann sich aber für einen begrenzten Wertebereich Makros für die Basisfunktionen Inkrement(n) und Dekrement(n) schreiben und daraus weitere Rechenoperationen wie Addition und Multiplikation ableiten. Die Boost.Preprocessor-Bibliothek tut genau dies für einen Wertebereich von 0 bis 255. Du kannst diese Bibliothek (die nur aus Header-Files besteht) nicht nur in C++, sondern auch in C nutzen. Edit: Folgender Beispielcode
1 | #include <boost/preprocessor.hpp> |
2 | |
3 | #define GPIO_TO_PIN(bank,gpio) BOOST_PP_STRINGIZE(BOOST_PP_ADD(BOOST_PP_MUL(32, bank),gpio))
|
4 | |
5 | close_gpio(GPIO_TO_PIN(3, 4)); |
wird vom Präprozessor expandiert zu
1 | close_gpio("100"); |
Edit2: Aber ehrlich gesagt frage ich mich auch, warum das Argument von close_gpio ein String und kein Integer sein sollte.
Im Falle der GCC, siehe: https://gcc.gnu.org/onlinedocs/cpp/Stringification.html Andere Compiler bzw. Präprozessoren bieten sicherlich ähnliche Features. Mit freundlichen Grüßen, Karol Babioch
Testi schrieb: > close_gpio ("27"); Sicher? Ich kann mir überhaupt nicht vorstellen, dass eine close_irgendwas-Funktionen ausgerechnet einen String benötigt. Welches System ist das? > ich möchte nun über den Präprozessor die 27 ausrechen lassen und dort > einfügen lassen. Also: > > #define GPIO_TO_PIN(bank,gpio) (32 * (bank) + (gpio)) Mach mit itoa() oder sprintf() einen String aus Deiner Preprozessor-Konstaten bzw. Makro. Wo ist das Problem?
Wenn man eine Funktion benutzt, die zur Laufzeit einen String parst, dann spielt es auch keine Rolle mehr, wenn man den String zur Laufzeit erzeugt.
Ja ist ein String. Das Programm läuft auf einem Embedded Linux und da werden die gpio ja export / unexport in Dateien geschrieben. Daher muss es ein String sein. Das mit itoa() und snprintf() hab ich auch schon überlegt, müsste aber dann die ganzen Funktionen umschreiben. Das mit dem Makro wäre halt schneller gegangen, es geht nur um das portieren des Programms auf ein anderes Board. Habe jetzt die paar Stellen von Hand auf den richtigen GPIO geändert. Mit dem Makro wäre es einfach "hübscher" gewesen. Das mit dem Boost ist aber richtig cool. Bin gerade noch am überlegen das reinzubauen :).
Hmm die boost gibts glaub net beim gcc linaro. Zumindet findet er den Header nicht.
Testi schrieb: > Das mit itoa() und snprintf() hab ich auch schon überlegt, müsste aber > dann die ganzen Funktionen umschreiben. Wieso denn das??? > Das mit dem Makro wäre halt > schneller gegangen, es geht nur um das portieren des Programms auf ein > anderes Board. Schreibe eine geeignete Funktion ins Makro, die genau das gewünschte macht. Ein grobschlächtiges Beispiel: char * myitoa (int i) { static char buf[16]; sprintf (buf, "%d", i); return buf; } > Mit dem Makro wäre es einfach "hübscher" gewesen. close_gpio(myitoa(GPIO_TO_PIN(0,27)))
Okay oder so... hätte angefangen die Funktionen so abzuänder, dass ich int übergebe und die selber Strings machen. So wäre es auch gegangen. Naja wie gesagt hab es bereits geändert.
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.