Exportieren und Importieren von Templates

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu C++-Spezifikation - Index


Template-Funktionen oder Klassen-Templates müssen ausreichend flexibel deklariert werden, um deren Verwendung in einer dynamischen Link-Bibliothek (gemeinsame Bibliothek) oder einer ausführbaren Datei zu ermöglichen. Dieselbe Template-Deklaration muss importierbar und/oder exportierbar oder ohne einen Modifizierer verfügbar sein. Um völlig flexibel zu sein, sollten in den Template-Deklarationen der Header-Datei die Modifizierer __export oder __import nicht verwendet werden. Dies ermöglicht es dem Benutzer, je nachdem wie die Instantiierung verwendet wird, den geeigneten Modifizierer bei der Instantiierung zuzuordnen.

Die folgenden Schritte demonstrieren das Exportieren und Importieren von Templates. Der Quelltext ist in drei Dateien organisiert. Bei Verwendung der Header-Datei wird der Quelltext in der DLL generiert.

  1. Exportierbare/Importierbare Template-Deklarationen
    Die Header-Datei enthält die Deklarationen aller Klassen-Templates und Template-Funktionen. Eine Version der Templates zum Exportieren/Importieren kann instantiiert werden, indem das passende Makro zur Compilierzeit definiert wird.
  2. Compilieren exportierbarer Templates
    Schreiben Sie den Quelltext für eine DLL. Nach dem Compilieren verfügt diese Bibliothek über wiederverwendbaren Quelltext zum Exportieren von Templates.
  3. Verwenden von Import-Templates
    Nun können Sie eine aufrufende Funktion schreiben, die Templates verwendet. Diese ausführbare Datei ist mit der DLL verknüpft. Nur Objekte, die nicht in der Header-Datei deklariert und in der Funktion "main" instantiiert sind, verursachen, dass der Compiler neuen Quelltext generiert. Quelltext für ein neu instantiiertes Objekt wird in die Datei "main.obj" geschrieben.

Explizites Instantiieren und Exportieren von Template-Membern aus exportierten Klassen

Wenn Sie eine Klasse exportieren, die Template-Member-Funktionen aus einer DLL oder einem Package enthält (mit der Direktive __declspec(dllexport) bzw. dem Makro PACKAGE), müssen diese Member explizit instantiiert und exportiert werden. Ansonsten könnten bei der Verwendung der exportierten Klasse Fehler aufgrund von nicht aufgelösten externen Definitionen in Bezug auf den Template-Member auftreten.

Beispiel:

mypackage.h:
#define PACKAGE __declspec(package)
class PACKAGE X
{
public:
  int foo();
  template<typename T>
  int bar(T *p)
  {
    return *p;
  }
};


mypackage.cpp:
#include "mypackage.h"
int X::foo()
{
  return 7;
}

Der obige Code befindet sich in einem C++-Package.

Die folgende App, die den Member "bar" aufruft, erzeugt einen Fehler aufgrund einer nicht aufgelösten externen Variable:

myapp.cpp:

#include "mypackage.h"

int g = 6;

int main()
{
  X x;
  x.foo();
  return x.bar(&g);
}
 Error:
 Error: Unresolved external 'int X::bar<int>(int*)' referenced from C:\USERS\ADMIN_000\APPDATA\LOCAL\TEMP\MYAPP-233656.O

Fügen Sie der Datei "mypackage.cpp" die folgende Zeile hinzu, um diesen Fehler zu beheben:

template PACKAGE int X::bar<int>(int*);

Der Code in der hinzugefügten Zeile instantiiert und exportiert die in der Quelldatei "myapp.cpp" verwendete Member-Template.