Wie kann ich die Vor-Hauptinitialisierung in C / C ++ mit avr-gcc durchführen?

8

Um sicherzustellen, dass ein bestimmter Initialisierungscode vor main (mit Arduino / avr-gcc) ausgeführt wird, habe ich einen Code wie den folgenden:

%Vor%

Idealerweise möchte ich einfach schreiben können:

%Vor%

aber das kompiliert nicht ...

Gibt es einen weniger ausführlichen Weg, um denselben Effekt zu erzielen?

Hinweis: Der Code ist Teil einer Arduino-Skizze, daher wird die main -Funktion automatisch generiert und kann nicht geändert werden (z. B. um initialize vor einem anderen Code aufzurufen).

Update: Idealerweise wird die Initialisierung in der Funktion setup durchgeführt, aber in diesem Fall gibt es anderen Code, der vor main auftritt.

    
Matthew Murdoch 04.06.2009, 11:08
quelle

9 Antworten

11

Sie können GCCs constructor Attribut um sicherzustellen, dass es vor main() aufgerufen wird:

%Vor%     
Adam Rosenfield 04.06.2009, 15:03
quelle
4

Sie können das Obige sehr geringfügig kürzer machen, indem Sie einen Rückgabetyp "initialisieren" und damit eine globale Variable initialisieren:

%Vor%

Sie müssen jedoch vorsichtig damit sein, der Standard garantiert nicht, dass die obige Initialisierung (oder die für Ihr init-Objekt) vor der Ausführung von main (3.6.2 / 3) stattfindet:

  

Es ist implementierungsdefiniert, ob die dynamische Initialisierung (8.5, 9.4, 12.1, 12.6.1) eines Objekts des Namensraumbereichs vor der ersten Anweisung von main erfolgt.

Das einzige, was garantiert ist, ist, dass die Initialisierung stattfindet, bevor 'dummy' jemals benutzt wird.

Eine aufdringlichere Option (wenn möglich) ist die Verwendung von "-D main = avr_main" in Ihrem Makefile. Sie könnten dann Ihren eigenen main wie folgt hinzufügen:

%Vor%

Zumindest ist hier garantiert, dass die Initialisierung stattfinden wird, wenn Sie es erwarten.

    
Richard Corden 04.06.2009 12:40
quelle
3

Hier ist eine etwas böse Methode, dies zu erreichen:

%Vor%

Fügen Sie den Linker-Flags Folgendes hinzu: --wrap main

zB

%Vor%

Der Linker ersetzt alle Aufrufe von main durch Aufrufe von __wrap_main , siehe ld man Seite auf --wrap

    
Hasturkun 04.06.2009 14:46
quelle
2

Ihre Lösung in einfach und sauber. Was Sie zusätzlich tun können, ist, Ihren Code in anonymen Namensraum zu setzen. Ich sehe keine Notwendigkeit, es besser zu machen:)

    
Piotr Dobrogost 04.06.2009 11:17
quelle
2

Wenn Sie die Arduino-Umgebung verwenden, gibt es einen Grund, warum Sie sie nicht in die Installationsmethode einfügen können?

Natürlich ist dies nach dem Arduino-spezifischen Hardware-Setup der Fall, also wenn Sie solche Low-Level-Zeug haben, dass es wirklich gehen muss, bevor main , dann brauchen Sie etwas Konstruktor Magie.

UPDATE:

Ok, wenn es vor dem main gemacht werden muss, denke ich, dass der einzige Weg darin besteht, einen Konstruktor zu verwenden, wie du es schon tust.

Sie können immer ein Präprozessor-Makro davon machen:

%Vor%

Das sollte jetzt funktionieren:

%Vor%

Aber es macht die Dinge nicht wirklich kürzer, sondern bewegt nur den ausführlichen Code herum.

    
CAdaker 04.06.2009 11:33
quelle
2

Sie können die Abschnitte ".init *" verwenden, um C-Code hinzuzufügen, der vor main () (und sogar der C-Laufzeit) ausgeführt werden soll. Diese Abschnitte werden am Ende in die ausführbare Datei eingebunden und zu einem bestimmten Zeitpunkt während der Programminitialisierung aufgerufen. Sie können die Liste hier bekommen:

Ссылка

.init1 zum Beispiel ist schwach an __init () gebunden, wenn Sie also __init () definieren, wird es verknüpft und als erstes aufgerufen. Der Stack wurde jedoch nicht eingerichtet, daher müssen Sie vorsichtig sein (verwenden Sie nur die Variable register8_t, rufen Sie keine Funktionen auf).

    
wesen 29.09.2009 10:36
quelle
0

Verwenden Sie statische Member von Klassen. Sie werden vor der Eingabe in main initialisiert. Der Nachteil ist, dass Sie die Reihenfolge der Initialisierung der statischen Klassenmitglieder nicht steuern können.

Hier ist Ihr Beispiel transformiert:

%Vor%     
Cătălin Pitiș 04.06.2009 11:17
quelle
0

Sicher, Sie haben dies in eine Ihrer Header-Dateien geschrieben, sagen Sie preinit.h:

%Vor%

und dann in eins Ihrer Kompilierungseinheiten:

%Vor%

Ich weiß, dass das ein Kludn ist, aber ich kenne keine portable Möglichkeit, eine Vor-Hauptinitialisierung durchzuführen, ohne einen Klassenkonstruktor zu verwenden, der im Dateibereich ausgeführt wird.

Sie sollten auch vorsichtig sein, mehr als eine dieser Initialisierungsfunktionen einzubeziehen, da ich nicht glaube, dass C ++ die Reihenfolge vorschreibt - es könnte zufällig sein.

Ich bin mir nicht sicher, von dieser "Skizze", von der Sie sprechen, aber wäre es möglich, die Hauptkompilierungseinheit mit einem Skript zu transformieren, bevor es an den Compiler übergeben wird, etwa so:

%Vor%

Sie können sehen, wie sich dies auf Ihr Programm auswirken würde, weil:

%Vor%

generiert Folgendes mit dem hinzugefügten initialize() -Aufruf:

%Vor%

Es kann sein, dass Sie die erzeugte Datei nicht nachbearbeiten können. In diesem Fall sollten Sie diese letzte Option ignorieren, aber das ist es, was ich zuerst betrachten würde.

    
paxdiablo 04.06.2009 11:17
quelle
0

Ich führe die Vor-Haupt-Codierung durch. Es gibt mehrere init-Abschnitte, die vor main ausgeführt werden. Dies bezieht sich auf Ссылка initN-Abschnitte.

>

Jedenfalls funktioniert das nur bei der -O-Optimierung aus irgendeinem Grund. Ich versuche immer noch herauszufinden, welche Option meinen Code vor der Hauptmontage "optimiert" hat.

%Vor%

Update, es stellt sich heraus, ich behauptete diese Funktion ist nicht verwendet, was dazu führt, dass die Routine weg zu optimieren. Ich sollte Funktion unbenutzte Warnung töten. Es wird stattdessen das verwendete Attribut verwendet.

    
Tan Xinyu 25.05.2016 10:56
quelle