5.2 Windowsversion

Das Laden der Bibliothek erfolgt mit einem Aufruf von LoadLibrary(); Ergebnis ist im Erfolgsfall vom Typ HINSTANCE (hinter dem sich wiederum ein void* verbirgt, welch ein Wunder!).

Freigeben kann man eine DLL mit FreeLibrary().

Mit GetProcAddress() kann man dann (analog zu dlsym() unter Linux) Zeiger auf die Objekte in der DLL holen.

///////////////////////////////////////////////////////////////////////
//
// Time-stamp: "(27.05.01 19:29) dynaufrufer.cpp [Klaus Wachtler]"
//
// kleine Demo zum Laden und Verwenden einer DLL.
// Kompilieren und Linken:
//    cl -GX dynaufrufer.cpp
// Zum Starten muß die demodll.dll im gleichen Verzeichnis sein
// (oder sonstwie erreichbar -> PATH-Variable).

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

// Typ: Zeiger auf Funktion, die int liefert, zwei int erhält:
typedef int ( __stdcall *int_intint_pf_t)( int, int );

// Typ: Zeiger auf Funktion, die int liefert, keine Parameter:
typedef int ( __stdcall *int_void_pf_t)( void );



int main()
{
  // Handle für geladene DLL:
  HINSTANCE  DLL_Handle = NULL;

  // Zeiger auf die Funktion in der DLL:
  int_intint_pf_t summe_pf = NULL;
  int_void_pf_t   immereinsmehr_pf = NULL;

  // einmalig die Bibliothek laden:
  DLL_Handle = LoadLibrary(  "demodll.dll");

  if( !DLL_Handle )
    {
      // Laden dder DLL hat nicht geklapppt!
      // Mit GetLastError() könnte man jetzt eine Kennung des
      // aufgetretenen Fehlers beschaffen; was man mit dieser Kennung
      // dann anstellt habe ich nicht verstanden :-(
      fprintf( stderr, "Fehler beim Laden der DLL!\n" );
      exit( 2 );
    }


  // Zeiger auf die darin enthaltenen Funktionen holen:
  summe_pf
    = (int_intint_pf_t)GetProcAddress( DLL_Handle, "summe" );
  immereinsmehr_pf
    = (int_void_pf_t)GetProcAddress( DLL_Handle, "immereinsmehr" );

  // Funktion gefunden?
  if( !summe_pf )
    {
      // Nö!
      fprintf( stderr,
               "Fehler! Funktion summe() nicht gefunden\n"
               );
      exit( 2 );
    }
  // Funktion gefunden?
  if( !immereinsmehr_pf )
    {
      fprintf( stderr,
               "Fehler! Funktion immereinsmehr() nicht gefunden\n"
               );
      exit( 2 );
    }

  // und beliebig oft benutzen:
  for( int i=0; i<10; i++ )
    {
      try
        {
          printf( "Summe von %d und %d ist %d; immer eins mehr ist %d\n",
                  i,
                  i/2,
                  (*summe_pf)( i, i/2 ),
                  (*immereinsmehr_pf)()
                  );
        }
      catch( int Fehler )
        {
          fprintf( stderr, "int-Ausnahme %d gefangen!\n", Fehler );
        }
      catch( ... )
        {
          fprintf( stderr, "irgendeine Ausnahme gefangen!\n" );
        }
      Sleep( 1000 );
    }

  // Mann kann die DLL auch wieder entladen, wenn man sie nicht
  // mehr braucht (FreeLibrary()).
  // Kann man sich aber auch sparen.

  FreeLibrary( DLL_Handle );

  return 0;
}

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

Das Beispielprogramm kann folgendermaßen übersetzt und gestartet werden (die Compileroption -GX ist nötig, weil Ausnahmen verwendet werden, was in C++ ja so ungewöhnlich ist!):

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

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

/out:dynaufrufer.exe
dynaufrufer.obj

C:\temp\dynBib\win32>dynaufrufer
DllMain: DLL_PROCESS_ATTACH
Summe von 0 und 0 ist 0; immer eins mehr ist 0
Summe von 1 und 0 ist 1; immer eins mehr ist 1
Summe von 2 und 1 ist 3; immer eins mehr ist 2
Summe von 3 und 1 ist 4; immer eins mehr ist 3
Summe von 4 und 2 ist 6; immer eins mehr ist 4
Summe von 5 und 2 ist 7; immer eins mehr ist 5
Summe von 6 und 3 ist 9; immer eins mehr ist 6
int-Ausnahme 125 gefangen!
int-Ausnahme 125 gefangen!
int-Ausnahme 125 gefangen!
DllMain: DLL_PROCESS_DETACH

Ein analoges Kommando zu ltrace gibt es meines Wissens unter Windows nicht.



www.wachtler.de