Schreiben von 64-Bit-Druckertreibern
Wichtig
Die Modern Print-Plattform ist die von Windows bevorzugte Methode zur Kommunikation mit Druckern. Wir empfehlen die Verwendung des Microsoft IPP-Treibers für die Posteingangsklasse zusammen mit Print Support Apps (PSA), um das Druckverhalten in Windows 10 und 11 für die Entwicklung von Druckergeräten anzupassen.
Weitere Informationen finden Sie unter Modern Print-Plattform und der Anleitung zum Design der Print-Support-App.
Wenn Sie einen 64-Bit-Treiber schreiben oder einen Treiber schreiben, der so kompiliert werden kann, dass er sowohl auf 32-Bit- als auch auf 64-Bit-Systemen läuft, befolgen Sie die Richtlinien für die 64-Bit-Portierung unter Portierung Ihres Treibers auf 64-Bit-Windows. Dieses Thema beschreibt einige der Grenzwerte und Probleme, auf die Sie beim Schreiben eines 64-Bit-Druckertreibers stoßen können.
Weitere Informationen zur Verwendung von Kennzeichnungen zur Identifizierung der 64-Bit-Architektur finden Sie in den folgenden Themen:
Grenzwerte für Gerätekontext-Handles
Wenn eine 32-Bit-Anwendung auf einer 64-Bit-Version des Microsoft Windows-Betriebssystems ausgeführt wird, sollte ein Druckertreiber-Plugin, das im Kontext des Thunking-Prozesses Splwow64.exe ausgeführt wird, die Funktion GDI CreateDC nicht anfragen; diese Anfrage wird fehlschlagen.
Probleme beim Schreiben von 64-Bit-Treibern
Seien Sie in vorhandenem 32-Bit-Treibercode vorsichtig bei Konvertierungen zwischen Pointer-Typen und Integer-Typen wie DWORD oder ULONG. Wenn Sie Erfahrung mit dem Schreiben von Code für 32-Bit- Rechner haben, sind Sie vielleicht an die Annahme gewöhnt, dass ein Zeigerwert in ein DWORD oder ULONG passt. Für 64-Bit-Code ist diese Annahme gefährlich. Wenn Sie einen Pointer auf den Typ DWORD oder ULONG casten, wird ein 64-Bit Pointer möglicherweise abgeschnitten.
Besetzen Sie den Pointer stattdessen mit dem Typ DWORD_PTR oder ULONG_PTR. Eine vorzeichenlose Ganzzahl vom Typ DWORD_PTR oder ULONG_PTR ist immer groß genug, um den gesamten Pointer zu speichern, unabhängig davon, ob der Code für einen 32-Bit- oder 64-Bit-Computer kompiliert wurde.
Das Pointer-Feld pDrvOptItems.UserData in der Struktur OEMCUIPPARAM ist zum Beispiel vom Typ ULONG_PTR. Das folgende Codebeispiel zeigt, was Sie nicht tun sollten, wenn Sie einen 64-Bit- Pointer-Wert in dieses Feld kopieren.
PUSERDATA pData;
OEMCUIPPARAM->pDrvOptItems.UserData = (ULONG)pData; // Wrong
Das vorangehende Codebeispiel überträgt den Pointer pData auf den Typ ULONG, wodurch der Pointerwert abgeschnitten werden kann, wenn sizeof(pData) >sizeof(ULONG). Der korrekte Ansatz ist, den Pointer in ULONG_PTR umzuwandeln, wie im folgenden Codebeispiel gezeigt.
PUSERDATA pData;
OEMCUIPPARAM->pDrvOptItems.UserData = (ULONG_PTR)pData; // Correct
Im vorangegangenen Codebeispiel bleiben alle 64 Bits des Pointers erhalten.
Inline 64-Bit-Funktionen wie PtrToUlong und UlongToPtr konvertieren sicher zwischen Pointer- und Integer-Typen, ohne sich auf Annahmen über die relativen Größen dieser Typen zu verlassen. Wenn ein Typ kürzer ist als der andere, muss er bei der Konvertierung in den längeren Typ erweitert werden. Wenn der kürzere Typ durch Auffüllen mit dem Vorzeichenbit oder mit Nullen erweitert wird, kann jede Win64-Funktion mit diesen Situationen umgehen. Betrachten Sie folgendes Codebeispiel.
ULONG ulHWPhysAddr[NUM_PHYS_ADDRS];
ulSlotPhysAddr[0] = ULONG(pulPhysHWBuffer) + HW_BUFFER_SIZE; // wrong
Ersetzen Sie das vorangegangene Codebeispiel durch das folgende Codebeispiel.
ULONG_PTR ulHWPhysAddr[NUM_PHYS_ADDRS];
ulSlotPhysAddr[0] = PtrToUlong(pulPhysHWBuffer) + HW_BUFFER_SIZE; // correct
Das zweite Code-Beispiel ist vorzuziehen, auch wenn
ulSlotPhysAddr
es den Wert eines Hardware-Registers darstellt, das nur 32 Bits lang ist und nicht 64 Bits lang. Eine Liste aller neuen Win64-Hilfsfunktionen für die Konvertierung zwischen Pointer- und Integer-Typen finden Sie unter Neue Datentypen.