Bagikan melalui


Menulis Driver Printer 64-Bit

Penting

Platform cetak modern adalah sarana komunikasi pilihan Windows dengan printer. Kami menyarankan agar Anda menggunakan driver kelas kotak masuk IPP Microsoft, bersama dengan Print Support Apps (PSA), untuk menyesuaikan pengalaman cetak di Windows 10 dan 11 untuk pengembangan perangkat printer.

Untuk informasi selengkapnya, lihat Platform cetak modern dan panduan desain aplikasi dukungan Cetak.

Jika Anda menulis driver 64-bit atau menulis driver yang dapat dikompilasi untuk dijalankan pada sistem 32-bit dan 64-bit, ikuti panduan port 64-bit di Porting Driver Anda ke Windows 64-Bit. Topik ini menjelaskan beberapa batasan dan masalah yang mungkin Anda temui dalam menulis driver printer 64-bit.

Untuk informasi selengkapnya tentang menggunakan dekorasi untuk mengidentifikasi arsitektur 64-bit, lihat topik berikut:

Batasan pada Handel Konteks Perangkat

Jika aplikasi 32-bit berjalan pada sistem operasi Microsoft Windows versi 64-bit, plug-in driver printer yang berjalan dalam konteks proses penghentian Splwow64.exe tidak boleh memanggil fungsi GDI CreateDC ; panggilan ini akan gagal.

Masalah dengan Menulis Driver 64-Bit

Dalam kode driver 32-bit yang ada, berhati-hatilah tentang konversi antara jenis pointer dan jenis bilangan bulat seperti DWORD atau ULONG. Jika Anda memiliki pengalaman menulis kode untuk komputer 32-bit, Anda mungkin terbiasa dengan asumsi bahwa nilai pointer cocok dengan DWORD atau ULONG. Untuk kode 64-bit, asumsi ini berbahaya. Jika Anda mentransmisikan pointer untuk mengetik DWORD atau ULONG, pointer 64-bit mungkin terpotong.

Sebagai gantinya, transmisikan pointer untuk mengetik DWORD_PTR atau ULONG_PTR. Bilangan bulat jenis DWORD_PTR atau ULONG_PTR yang tidak ditandatangani selalu cukup besar untuk menyimpan seluruh penunjuk, terlepas dari apakah kode dikompilasi untuk komputer 32-bit atau 64-bit.

Misalnya, bidang pointer pDrvOptItems.UserData di struktur OEMCUIPPARAM berjenis ULONG_PTR. Contoh kode berikut menunjukkan apa yang tidak boleh dilakukan jika Anda menyalin nilai pointer 64-bit ke bidang ini.

PUSERDATA pData;
OEMCUIPPARAM->pDrvOptItems.UserData = (ULONG)pData;  // Wrong

Contoh kode sebelumnya mentransmisikan pointer pData untuk mengetik ULONG, yang dapat memotong nilai pointer jika sizeof(pData)> sizeof(ULONG). Pendekatan yang benar adalah melemparkan penunjuk ke ULONG_PTR, seperti yang ditunjukkan dalam contoh kode berikut.

PUSERDATA pData;
OEMCUIPPARAM->pDrvOptItems.UserData = (ULONG_PTR)pData;  // Correct

Contoh kode sebelumnya mempertahankan semua 64 bit nilai pointer.

Fungsi 64-bit sebaris seperti PtrToUlong dan UlongToPtr dengan aman mengonversi antara jenis pointer dan bilangan bulat tanpa mengandalkan asumsi tentang ukuran relatif dari jenis ini. Jika satu jenis lebih pendek dari yang lain, jenis tersebut harus diperpanjang saat mengonversi ke jenis yang lebih panjang. Jika jenis yang lebih pendek diperluas dengan mengisi dengan bit tanda atau dengan nol, setiap fungsi Win64 dapat menangani situasi ini. Perhatikan contoh kode berikut.

ULONG ulHWPhysAddr[NUM_PHYS_ADDRS];
ulSlotPhysAddr[0] = ULONG(pulPhysHWBuffer) + HW_BUFFER_SIZE;  // wrong

Anda harus mengganti contoh kode sebelumnya dengan contoh kode berikut.

ULONG_PTR ulHWPhysAddr[NUM_PHYS_ADDRS];
ulSlotPhysAddr[0] = PtrToUlong(pulPhysHWBuffer) + HW_BUFFER_SIZE;  // correct

Contoh kode kedua lebih disukai meskipun

ulSlotPhysAddr

mungkin mewakili nilai register perangkat keras yang panjangnya hanya 32 bit, bukan 64 bit. Untuk daftar semua fungsi pembantu Win64 baru untuk mengonversi antara jenis pointer dan bilangan bulat, lihat Jenis Data Baru.