Verwendung die C-Laufzeit

Zusammenfassung

Dieses Dokument enthält die folgenden Abschnitte:
Abschnitt 1: Stehen drei Formen der C Laufzeitbibliothek (CRT)
Abschnitt 2: Verwendung der CRT-Bibliotheken bei Erstellung einer DLL
Abschnitt 3: Verwenden von NTWIN32. MAK vereinfacht das Erstellen
Abschnitt 4: Probleme bei mehreren CRT-Bibliotheken
Abschnitt 5: Mischen Bibliothek

Weitere Informationen

Abschnitt 1: Stehen drei Arten von C Laufzeitbibliotheken (CRT)


Es werden drei Formen der C-Laufzeit-Bibliothek im Win32-SDK:

  • LIBC. LIB wird eine statisch verknüpfte Bibliothek für Singlethreadprogramme.
  • LIBCMT. LIB wird eine statisch verknüpfte Bibliothek, die Multithreadprogramme unterstützt.
  • CRTDLL. LIB ist Importbibliothek CRTDLL. DLL, die Multithreadprogramme unterstützt. CRTDLL. DLL selbst ist Teil von Windows NT.
Microsoft Visual C++ 32-Bit-Edition enthält ebenfalls diese drei Formulare, jedoch heißt CRT in einer DLL MSVCRT. LIB. Die DLL ist redistributable. Seinen Namen hängt von der Version von VC++ (ie MSVCRT10. DLL oder MSVCRT20. (DLL). Beachten Sie jedoch, dass MSVCRT10. DLL wird auf Win32s während CRTDLL nicht unterstützt. LIB wird auf Win32s unterstützt. MSVCRT20. DLL ist in zwei Versionen: eine für Windows NT und die andere für Win32s.


Abschnitt 2: Verwendung der CRT-Bibliotheken bei Erstellung einer DLL



Beim Erstellen einer C-Laufzeit-Bibliothek verwendet, um sicherzustellen, dass einer DLL ist CRT ordnungsgemäß, entweder initialisiert

  1. die Initialisierungsfunktion muss den Namen DllMain() und Linker Option-entry:_DllMainCRTStartup@12 - Einstiegspunkt angegeben werden-


  2. der DLL-Einstiegspunkt muss explizit aufrufen CRT_INIT() Prozess und Anfügen an einen Prozess
Die C-Laufzeitbibliotheken ordnungsgemäß und C Run-Time-Daten zu initialisieren, wenn ein Prozess oder Thread Anfügen an die DLL C Run-Time Daten ordnungsgemäß bereinigen, wenn ein Prozess trennen, aus der DLL und globaler C++-Objekte in der DLL ordnungsgemäß erstellt und zerstört werden können.


Alle Win32-SDK-Beispiele verwenden die erste Methode. Als Beispiel verwenden. Außerdem finden Sie in der Win32-Programmierreferenz DllEntryPoint() und Visual C++-Dokumentation für DllMain(). Beachten Sie, dass DllMainCRTStartup() CRT_INIT() und CRT_INIT() rufen die Anwendung DllMain() falls vorhanden.


Möchten Sie die zweite Methode und Initialisierungscode CRT, DllMainCRTStartup() und DllMain(), rufen gibt es zwei Verfahren:

  1. ist kein Eintrag-Funktion die Initialisierungscode durchführt, geben Sie einfach CRT_INIT() als Einstiegspunkt der DLL. Sofern Sie NTWIN32 hinzugefügt haben. MAK, die DLLENTRY als "@12" definiert die DLL Verknüpfungslinie folgende Option hinzufügen:
    -Entry:_CRT_INIT$(DLLENTRY)
    – oder –


  2. Wenn Sie * * haben eigene DLL-Einstiegspunkt zeigen, gehen Sie in den Einstiegspunkt:


    1. Verwenden Sie diesen Prototyp für CRT_INIT():
      BOOL WINAPI CRT_INIT (HINSTANCE HinstDLL DWORD FdwReason, LPVOID LpReserved);
      Informationen zu CRT_INIT() Werte finden Sie in der Dokumentation DllEntryPoint; dieselben Werte werden zurückgegeben.
    2. DLL_PROCESS_ATTACH und DLL_THREAD_ATTACH (siehe "DllEntryPoint" in der Win32-API Weitere Informationen zu diesen Flags verweisen), rufen Sie CRT_INIT(), zunächst vor alle C-Laufzeit Funktionen aufgerufen werden oder alle Gleitkommaoperationen durchgeführt.
    3. Eigener Prozess/Thread Initialisierung/Beendigung Code aufrufen.
    4. DLL_PROCESS_DETACH und DLL_THREAD_DETACH rufen Sie CRT_INIT(), nachdem alle C-Laufzeitfunktionen aufgerufen wurde und alle Gleitkomma Operationen abgeschlossen sind.
    Übergeben Sie unbedingt auf CRT_INIT() Parameter den Eintrag zeigen. CRT_INIT() erwartet die Parameter Dinge nicht zuverlässig funktionieren, wenn sie ausgelassen (insbesondere FdwReason ist erforderlich, um festzustellen, ob ein Prozess oder Beendigung erforderlich ist).


    Es folgt eine Skelett Beispiel Einstiegspunktfunktion, die zeigt, wann und wie Sie diese CRT_INIT() in der DLL-Einstiegspunkt aufrufen:
        BOOL WINAPI DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason,        LPVOID lpReserved)
    {
    if (fdwReason == DLL_PROCESS_ATTACH || fdwReason == DLL_THREAD_ATTACH)
    if (!_CRT_INIT(hinstDLL, fdwReason, lpReserved))
    return(FALSE);

    if (fdwReason == DLL_PROCESS_DETACH || fdwReason == DLL_THREAD_DETACH)
    if (!_CRT_INIT(hinstDLL, fdwReason, lpReserved))
    return(FALSE);
    return(TRUE);
    }

    Beachten Sie, dass dies * nicht * erforderlich, wenn Sie DllMain() und -entry:_DllMainCRTStartup@12 verwenden.

Abschnitt 3: Verwenden von NTWIN32. MAK vereinfacht das Erstellen


Werden Makros in NTWIN32 definiert. MAK, die verwendet werden, um die Makefiles zu vereinfachen und sicherzustellen, dass sie ordnungsgemäß erstellt werden, um Konflikte zu vermeiden. Aus diesem Grund empfiehlt Microsoft dringend NTWIN32. MAK und Makros darin.


Für die Kompilierung verwendet:

   $(cvarsdll)          for apps/DLLs using CRT in a DLL


Verknüpfung, verwenden Sie eine der folgenden:

   $(conlibsdll)        for console apps/DLLs using CRT in a DLL
$(guilibsdll) for GUI apps using CRT in a DLL

Abschnitt 4: Probleme bei mehreren CRT-Bibliotheken


Eine Anwendung, die C-Laufzeit Aufrufe in eine DLL, macht C-Laufzeit-Aufrufe auch darauf achten, dass bei Verknüpfung werden sie sowohl mit der statisch verknüpften C-Laufzeitbibliotheken (LIBC. verknüpft. LIB oder LIBCMT. LIB) die. EXE und die DLL müssen separate Kopien aller C-Laufzeitfunktionen und globale Variablen. Dies bedeutet, dass C Run-Time-Daten zwischen nicht die. EXE und die DLL. Daher werden einige der Probleme, die auftreten können:

  • Übergeben von gepufferten Stream Handles aus dem. EXE/DLL in das Modul
  • Speicher mit einer C-Laufzeit in der. EXE/DLL zuordnen und freigeben in das andere Modul
  • Überprüfen oder Festlegen des Werts der globalen Errno Variablen in der. EXE/DLL und erwartet in das Modul. Ein Problem ist der Aufruf von perror() im gegenüberliegenden Modul aus dem C Run - Time Fehler perror() Errno verwendet.
Um diese Probleme zu vermeiden, verknüpfen Sie sowohl die. EXE und die DLL mit CRTDLL. LIB oder MSVCRT. LIB, wodurch sowohl die. EXE und der DLL, die allgemeine Funktionen CRT in einer DLL enthaltenen Daten und C Run-Time-Daten wie Stream Handles verwenden dann gemeinsam sowohl die. EXE und der DLL.

Abschnitt 5: Mischen Bibliothek


Sie können die DLL mit CRTDLL verknüpfen. LIB/MSVCRT. LIB unabhängig davon, was Ihr. EXE ist mit verknüpft, wenn Sie CRT-Datenstrukturen mischen und Dateihandles CRT oder CRT-Datei * Zeiger an andere Module vermeiden.


Beim Mischen Bibliothekstypen Folgendes beachten:

  • CRT Dateihandles auf CRT-Modul darf nur, die sie erstellt haben.
  • CRT-Datei * Zeiger auf CRT-Modul darf nur, die sie erstellt haben.
  • Speicher mit CRT-Funktion malloc() kann nur freigegeben oder zugewiesen vom CRT-Modul, das zugewiesen.
Um dies zu veranschaulichen, Beispiel:

   - .EXE is linked with MSVCRT.LIB
- DLL A is linked with LIBCMT.LIB
- DLL B is linked with CRTDLL.LIB

Wenn die. EXE erstellt ein CRT-Dateihandle mit _create() oder _open(), Datei-Handle kann nur auf _lseek(), _read(), _write(), _close() usw. übergeben die. EXE-Datei. Geben Sie nicht dieses Handle CRT-Datei oder DLL. Abgerufen aus einer DLL zu der DLL oder CRT-Dateihandle nicht übergeben die. EXE.




Wenn A DLL einen Speicherblock mit malloc() zuordnet, kann nur DLL A free(), _expand() oder realloc() auf diesem Block aufrufen. Nicht malloc() A DLL aufrufen und versuchen, dieses Blocks aus der. EXE oder DLL B.




Hinweis: Wenn alle drei Module mit CRTDLL verknüpft wurden. LIB oder alle drei wurden mit MSVCRT verknüpft. LIb, gilt diese Einschränkung nicht.

Beim Verknüpfen von DLLs mit LIBC. LIB, beachten Sie, dass ist eine Möglichkeit, dass eine DLL von Multithreadprogrammen aufgerufen wird, die DLL nicht unterstützt mehrere Threads aus der DLL gleichzeitig, die Probleme verursachen können. Besteht die Möglichkeit, die DLL Multithreadprogramme aufgerufen wird, sollten Sie mit Bibliotheken verknüpfen, die unterstützen Multithreadprogramme (LIBCMT. LIB CRTDLL. LIB oder MSVCRT. LIB).
Eigenschaften

Artikelnummer: 94248 – Letzte Überarbeitung: 14.01.2017 – Revision: 1

Feedback