3.2 Bibliothek Windowsversion

Neben den beiden eigentlich genutzten Funktionen ist noch die Funktion DllMain() enthalten, die beim Laden und Entladen der DLL aufgerufen wird (siehe Einsprungpunkte beim Laden oder Entladen einer dynamischen Bibliothek).

Damit ein Aufrufer irgendwelche globalen Namen (wie hier die Funktionsnamen) ansprechen kann, müssen diese mit __declspec(dllexport) deklariert werden.

///////////////////////////////////////////////////////////////////////
//
// Time-stamp: "(09.05.01 20:00) demodll.cpp [Klaus Wachtler]"
//
//
// Kompilieren mit:
//  cl -LD -GX demodll.cpp
//

static int    Wert = 0;

extern "C" __declspec(dllexport) int summe( int a, int b )
{
  return a + b;
}

extern "C" __declspec(dllexport) int immereinsmehr( void )
{
  if( Wert>6 )
    {
      throw( 125 );
    }

  return Wert++;
}

// Ab hier kann der ganze Rest entfallen, wenn man ihn nicht braucht:

#include <stdio.h>
#include <windows.h>
#include <winbase.h>


// ModulHandle ist das "module handle" resp. "instance handle".
BOOL APIENTRY DllMain( HANDLE ModulHandle, 
		       DWORD  InitOderExit, 
		       LPVOID lpReserved
		       )
{
  switch( InitOderExit )
    {
    case DLL_PROCESS_ATTACH:
      // Die DLL wird in den Adreßraum eines Prozesses eingeblendet
      // (z.B. durch ein LoadLibrary() bei explizitem Laden, oder
      // durch Programmstart bei implizitem Linken über DEF-Dateien).
      // Entspricht dem Starten eines normalen Programms.
      // Guter Moment, um globale Variablen zu initialisieren etc.

      fprintf( stderr, "DllMain: DLL_PROCESS_ATTACH\n" );

      break;

    case DLL_THREAD_ATTACH:
      // Der zugehörige Prozeß hat einen neuen thread gestartet.
      // Hier könnte man thrad local storage allokieren (TlsAlloc())

      fprintf( stderr, "DllMain: DLL_THREAD_ATTACH\n" );

      break;

    case DLL_THREAD_DETACH:
      // Der zugehörige Prozeß hat einen thread gestoppt.
      // Gegenstück zu DLL_THREAD_ATTACH.

      fprintf( stderr, "DllMain: DLL_THREAD_DETACH\n" );

      break;

    case DLL_PROCESS_DETACH:
      // Die DLL wird aus dem Prozeßraum eines Prozesses entfernt
      // (durch Ende des Prozesses oder durch FreeLibrary()).
      // Gegenstück zu DLL_PROCESS_ATTACH.
      // Hier kann man globale Objekte wieder aufräumen.

      fprintf( stderr, "DllMain: DLL_PROCESS_DETACH\n" );

      break;

    default:
      // sollte eigentlich nie vorkommen!

      fprintf( stderr, "DllMain: DLL_???\n" );

      break;
    }

  // Rückgabewert von DllMain() sollte !=(0) sein, wenn alles ok ist.
  // Die DLL gilt dann als erfolgreich geladen.
  // Im Fehlerfall sollte DllMain() (0) liefern.
  // Dann liefert LoadLibrary() dem aufrufenden Prozeß einen Wert
  // ungleich 0 (also "gescheitert) bei explizitem Linken, bzw.
  // bei implizitem Linken wird der gerade startende Prozeß
  // abgeschossen.

  return TRUE;
}

//                                                                       
///////////////////////////////////////////////////////////////////////

Die Beispielbibliothek kann folgendermaßen übersetzt werden:

C:\temp\dynBib\win32>cl -LD -GX demodll.cpp
Optimierender Microsoft (R) 32-Bit C/C++-Compiler, Version 12.00.8168, fuer x86
Copyright (C) Microsoft Corp 1984-1998. Alle Rechte vorbehalten.

demodll.cpp
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:demodll.dll
/dll
/implib:demodll.lib
demodll.obj
   Bibliothek demodll.lib und Objekt demodll.exp wird erstellt
Die wesentlichen daraus entstehenden Dateien sind demodll.lib und demodll.dll.

Die LIB-Datei wird benötigt, um die Bibliothek fest an ein Programm zu linken.

Die DLL wird sowohl zum festen Linken als auch zum dynamischen Nachladen nach Programmstart benötigt.



www.wachtler.de