Code vor main() ausführen

Lesezeit: 3 Minuten

In objektorientierten Sprachen (C++) können Sie vorher Code ausführen main() indem Sie ein globales Objekt oder ein statisches Klassenobjekt verwenden und deren Konstruktoren den gewünschten Code ausführen lassen.

Gibt es eine Möglichkeit, dies in C zu tun? Ich habe kein bestimmtes Problem, das ich lösen möchte, ich bin nur neugierig. Eine Sache, für die dies nützlich sein könnte, ist die automatische Initialisierung einer Bibliothek.

  • stackoverflow.com/questions/949890/…

    – Stapler

    3. Januar 2012 um 14:13 Uhr

  • @stacker – Die Frage, auf die Sie sich beziehen, ist spezifisch für die Arduino-Umgebung. Wie auch immer, Antworten dort können hilfreich sein.

    – mouviciel

    3. Januar 2012 um 14:18 Uhr

  • Nicht in irgendeiner standardkonformen Weise, aber Sie sollten sich damit befassen, was wirklich passiert, wenn Ihr Betriebssystem das Binärabbild lädt und die Hauptfunktion der Anwendung aufruft!

    – Christoffer

    3. Januar 2012 um 14:29 Uhr

Benutzer-Avatar
Dan Fego

Du kannst es mit machen __attribute__ ((constructor)). Ich habe das folgende Beispiel mit beiden getestet gcc und clang. Davon abgesehen ist es nicht Teil der Sprache.

#include <stdio.h>

void __attribute__ ((constructor)) premain()
{
    printf("premain()\n");
}

int main(int argc, char *argv[])
{
    printf("main()\n");
    return 0;
}

Es macht Folgendes:

$ ./test
premain()
main()

GCC dokumentiert es unter: https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes

Benutzer-Avatar
Sangeeth Saravanaraj

Es gibt Möglichkeiten zu verwenden __attribute__ aber diese sind sehr spezifisch für Ihren Compiler und Code, der mit diesen geschrieben wurde nicht wirklich tragbar. Andererseits bietet die C-Sprache keine Startmodule/Bibliotheken.

Logischerweise in C main() ist die erste Funktion, die vom Betriebssystem aufgerufen wird. Aber bevor Sie anrufen main()ruft das Betriebssystem eine andere Funktion namens auf start-up Modul zum Einrichten verschiedener Umgebungsvariablen, Initialisieren (nicht initialisierter) statischer Variablen, Erstellen eines Stapelrahmens (Aktivierungsdatensatz) und Initialisieren des Stapelzeigers auf den Anfang des Stapelbereichs und andere Aufgaben, die vor dem Aufrufen erledigt werden müssen main().

Angenommen, Sie schreiben Code für eingebettete Systeme, bei denen es kein oder nur ein minimales Betriebssystem gibt, um die oben genannte Arbeit zu erledigen, dann sollten Sie diese Compiler-abhängigen Optionen untersuchen. Anders als GCC bieten Turbo-C- und Microsoft C-Compiler Einrichtungen zum Hinzufügen von Code in einer bestimmten Hardware-Maschine (z. B. 8086-Maschinen).

Mit anderen Worten, die Startmodule sind nicht für Programmierer gedacht.

  • Falsch, main ist nicht die erste Funktion, die vom Betriebssystem aufgerufen wird. Hast du von … gehört crt0? _start wird immer vorher aufgerufen mainund unter Windows, WinMain wird vorher aufgerufen main Auch.

    – MDXF

    16. Mai 2017 um 21:34 Uhr


  • Das ist falsch! _start wird vom Betriebssystem aufgerufen. _start ruft im Allgemeinen (basierend auf Ihrem Compiler) __libc_start_main auf, das main aufruft.

    – Zac Wimer

    3. November 2018 um 6:01 Uhr

Mit gcc können Sie dies tun, indem Sie das Konstruktorfunktionsattribut verwenden, z

__attribute__ ((__constructor__)) 
void foo(void) {
        ...
}

Dadurch wird foo vor main aufgerufen.

Hinweis: Dies ist wahrscheinlich nicht auf andere Compiler portierbar.

Sie können globale Variablen initialisieren, aber innerhalb dieser Initialisierungen keine Funktionen aufrufen.

Wenn Ihr Compiler cpp-Dateien kompilieren kann, können Sie eine Datei mit einer Klasse hinzufügen, die im Costructor Ihren Initialisierungscode aufruft. Die Klasse muss statisch zugewiesen werden. Zum Beispiel:

#include "ext.h"

class cext
{
public:
   cext()
   {
      ExtInit();
   }

   ~cext(){};
};

cext g_cext;

Die ExtInit()-Funktion muss als extern “C” in der Datei ext.h definiert werden.

#ifdef __cplusplus
extern "C" {
#endif
void   ExtInit   (void);
#ifdef __cplusplus
}
#endif

  • Und dies zieht die gesamte C++-Laufzeitbibliothek hinein und bindet jeden, der den Code verwenden möchte, an diese eine bestimmte C++-Laufzeit. Es gibt einen Grund, warum die Frage mit C und nicht mit C++ gekennzeichnet wurde.

    – Andreas Henle

    2. Februar um 17:11 Uhr

  • Und dies zieht die gesamte C++-Laufzeitbibliothek hinein und bindet jeden, der den Code verwenden möchte, an diese eine bestimmte C++-Laufzeit. Es gibt einen Grund, warum die Frage mit C und nicht mit C++ gekennzeichnet wurde.

    – Andreas Henle

    2. Februar um 17:11 Uhr

1368040cookie-checkCode vor main() ausführen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy