Frage

Dies ist Teil einer Reihe von mindestens zwei eng verwandten, aber unterschiedlichen Fragen. Ich hoffe, ich mache das Richtige, indem ich sie separat frage.

Ich versuche, meine visuelle C ++ 2008 -App ohne die C -Laufzeitbibliothek zu funktionieren. Es ist eine Win32 -GUI -App ohne MFC oder andere schicke Sachen, einfach nur Windows -API.

Daher setze ich Projekteigenschaften -> Konfiguration -> C/C ++ -> Erweitert -> Standardbibliotheksnamen auf Ja (Compiler Flag /Zl) und wieder aufgebaut.

Dann beschwert sich der Linker über ein ungelöstes Äußeres _WinMainCRTStartup. Fair genug, kann ich dem Linker sagen, er solle einen anderen Einstiegspunkt verwenden, sagen wir MyStartup. Nach dem, was ich im Internet sammle, _WinMainCRTStartup Macht einige Initialisierungssachen, und ich will wahrscheinlich MyStartup eine Teilmenge davon durchführen.

Meine Frage ist also: Welche Funktionen tun _WinMainCRTStartup Durchführen und welche davon kann ich weglassen, wenn ich die CRT nicht benutze?

Wenn Sie sich über dieses Zeug auskennen, schauen Sie sich bitte einen Blick auf meine andere Frage zu. Vielen Dank!

Abgesehen davon: Warum möchte ich das überhaupt erst machen?

  1. Meine App verwendet keine explizit CRT -Funktionen.
  2. Ich mag schlanke und gemeine Apps.
  3. Es wird mir etwas Neues beibringen.
War es hilfreich?

Lösung

Der Einstiegspunkt des CRT macht Folgendes (diese Liste ist nicht abgeschlossen):

  • Initialisiert der vom CRT benötigte Global State. Wenn dies nicht erledigt ist, können Sie keine Funktionen oder Status verwenden, die von der CRT bereitgestellt werden.
  • Initialisiert einen globalen Zustand, der vom Compiler verwendet wird. Laufzeitüberprüfungen wie das von /GS verwendete Sicherheitskeks. Du kannst anrufen __Security_init_cookie Sie selbst. Möglicherweise müssen Sie einen anderen Code für andere Laufzeitprüfungen hinzufügen.
  • Ruft Konstruktoren auf C ++ - Objekten auf. Wenn Sie C ++ - Code schreiben, müssen Sie dies möglicherweise emulieren.
  • Ruft die Befehlszeile ab und starten Sie Informationen, die vom Betriebssystem bereitgestellt werden, und übergeben sie Ihre Hauptdaten. Standardmäßig werden keine Parameter vom Betriebssystem an den Einstiegspunkt des Programms übergeben - sie werden alle von der CRT zugewiesen.

Der CRT -Quellcode ist mit Visual Studio erhältlich und Sie können den Einstiegspunkt des CRT in einem Debugger durchlaufen und genau herausfinden, was er tut.

Andere Tipps

EIN Stimmt Das in C (nicht C ++) geschriebene Win32 -Programm benötigt überhaupt keine Initialisierung, sodass Sie Ihr Projekt mit starten können Winmaincrtstartup () Anstatt von Winmain (Hinstance, ...).

Es ist auch möglich, aber etwas schwieriger, Konsolenprogramme als echte Win32 -Anwendungen zu schreiben. Der Standardname des Einstiegspunkts ist _maincrtstartup ().

Deaktivieren Sie alle Funktionen für zusätzliche Codegenerierung wie Stack -Sonden, Array -Checks usw. Debugging ist immer noch möglich.

Initialisierung

Manchmal brauchst du das erste Hinstanz Parameter. Für Win32 (außer Win32s) ist es an fixiert an (Hinstance) 0x400000.

Das ncmdshow Parameter ist immer Sw_showdefault.

Rufen Sie bei Bedarf die Befehlszeile mit mit GetCommandline ().

Beendigung

Wenn Ihr Programm Threads hervorbringt, z. B. anrufen GetopenFileName (), Rückkehr von Winmaincrtstartup () mit Rückkehr Das Schlüsselwort hängt Ihr Programm auf - verwenden Sie ExitProcess () stattdessen.

Vorbehalte

Sie werden in beträchtlichen Schwierigkeiten geraten, wenn:

  • Verwenden von Stackrahmen (dh lokale Variablen) größer als 4 kByte (pro Funktion)
  • Verwenden von Float-Point-Arithmetik (z. B. Float-> int-Umwandlung)
  • Mit 64-Bit-Ganzzahlen auf 32-Bit-Maschinen (multiplizieren, Bitverschiebungsvorgänge)
  • mit C ++ Neu, löschen, und statische Objekte mit Konstruktoren ohne Null-Out-Memitern
  • Verwenden von Standardbibliotheksfunktionen wie fopen (), printf () Natürlich

Fehlerbehebung

In allen Windows -Systemen ist eine C -Standardbibliothek verfügbar (da Windows 95), die Msvcrt.dll.

Um es zu verwenden, importieren Sie ihre Einstiegspunkte, z. B. mit meinem msvcrt-light.lib (Google dafür). Es gibt jedoch noch einige Vorbehalte, insbesondere wenn Compiler neuer als MSVC6 verwendet werden:

  • Stackrahmen sind immer noch auf 4 KByte begrenzt
  • _ftol_sse oder _ftol2_sse muss aufgeleitet werden zu _ftol
  • _iob_func muss aufgeleitet werden zu _iob

Die Initialisierung scheint zur Ladezeit zu laufen. Zumindest die Dateifunktionen werden scheinbar ausgeführt.

Alte Frage, aber die Antworten sind entweder falsch oder konzentrieren sich auf ein bestimmtes Problem.

Es gibt eine Reihe von C- und C ++ - Funktionen, die einfach nicht unter Windows (oder den meisten Betriebssystemen) verfügbar sind, wenn die Programme tatsächlich bei Main/WinMain begonnen haben.

Nehmen Sie dieses einfache Beispiel:

class my_class
{
public:
    my_class() { m_val = 5; }
    int my_func(){ return m_val }
private:
    int m_val;
}

my_class g_class;

int main(int argc, char **argv)
{
     return g_class.my_func();
}

Damit dieses Programm wie erwartet funktionieren kann, muss der Konstruktor für my_class vor dem Main aufgerufen werden. Wenn das Programm genau bei Main begann, würde ein Compiler -Hack (Hinweis: GCC in einigen Fällen) erforderlich sein, um einen Funktionsaufruf zu Beginn des Mains einzufügen. Stattdessen konstruiert in den meisten OSS und in den meisten Fällen eine andere Funktion G_CLASS und ruft dann Main auf (unter Windows, dies ist entweder MaincrtStartup oder WinMaincrtStartup; Bei den meisten anderen Osen ist ich eine Funktion, die als Start bezeichnet wird).

Es gibt noch andere Dinge, die C ++ und sogar C vor oder nach der Arbeit erledigt werden müssen. Wie sind Stdin und Stdout (Std :: Cin und Std :: Cout), sobald der Hauptstart startet? Wie funktioniert Atexit?

Der C-Standard erfordert, dass die Standardbibliothek eine POSIX-ähnliche Signal-API hat, die vor Main () "installiert" werden muss.

Bei den meisten OSS gibt es keinen systembereiteten Haufen; Die C -Laufzeit implementiert einen eigenen Heap (Microsoft C -Laufzeit wickelt nur die Kernel32 -Heap -Funktionen).

Sogar die Argumente an Main, Argc und Argv, müssen irgendwie aus dem System erhalten werden.

Vielleicht möchten Sie einen Blick auf Matt Pietricks (alte) Artikel über die Implementierung seiner eigenen C -Laufzeit für Einzelheiten darüber werfen, wie dies mit Windows + MSVC funktioniert ):http://msdn.microsoft.com/en-us/library/bb985746.aspx

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top