Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Kodunuzu hem 32 hem de 64 bit Microsoft Windows için derlemek üzere taşıma işlemi basittir. İşaretçileri atamayla ilgili yalnızca birkaç basit kurala uymanız ve kodunuzda yeni veri türlerini kullanmanız gerekir. İşaretçi işleme kuralları aşağıdaki gibidir.
int, uzun, ULONGveya DWORDişaretçileri atamayın.
Bazı bitleri test etmek, bitleri ayarlamak veya temizlemek ya da içeriğini başka bir şekilde işlemek için bir işaretçi atamanız gerekiyorsa, UINT_PTR veya INT_PTR türünü kullanın. Bu türler, hem 32 hem de 64 bit Windows için işaretçi boyutuna ölçeklendirilen integral türleridir (örneğin, 32 bit Windows için ULONG ve 64 bit Windows için _int64). Örneğin, aşağıdaki kodu taşımanız gerekir:
ImageBase = (PVOID)((ULONG)ImageBase | 1);Taşıma işleminin bir parçası olarak kodu aşağıdaki gibi değiştirebilirsiniz:
ImageBase = (PVOID)((ULONG_PTR)ImageBase | 1);uygun yerlerde UINT_PTR ve INT_PTR kullanın (ve gerekli olup olmadığından emin değilseniz, her ihtimale karşı kullanmanın bir zararı yoktur). İşaretçilerinizi ULONG, LONG, INT, UINTveya DWORDtürlerine dönüştürmeyin.
HANDLE, void*olarak tanımlandığına dikkat edin; bu yüzden HANDLE değerini ULONG değerine tür dönüştürme yaparak düşük dereceli 2 biti test etmek, ayarlamak veya temizlemek 64-bit Windows sistemlerinde hatalı bir işlemdir.
İşaretçileri kırpmak için PtrToLong veya PtrToUlong işlevini kullanın.
bir işaretçiyi 32 bitlik bir değere kesmeniz gerekiyorsa, PtrToLong veya PtrToUlong işlevini (Basetsd.h içinde tanımlanır) kullanın. Bu işlevler, çağrı süresi boyunca işaretçi kesme uyarısını devre dışı bırakır.
Bu işlevleri dikkatli bir şekilde kullanın. Bu işlevlerden birini kullanarak bir işaretçi değişkenini dönüştürdükten sonra, bir daha işaretçi olarak kullanmayın. Bu fonksiyonlar, genellikle başlangıçta bir işaretçi tarafından başvurulan belleğe erişmek için gerekli olan bir adresin üst 32 bitini keser. Bu işlevleri dikkatli bir şekilde dikkate almadan kullanmak, hassas kodlara neden olur.
64-bit kod olarak derlenebilecek kodda POINTER_32 değerlerini kullanırken dikkatli olmalısınız. Derleyici, işaretçiyi 64 bitlik kodda yerel bir işaretçiye atandığında sıfır genişletme yapmayıp işaret uzatması yapacaktır.
Kodda 32 bit kod olarak derlenmiş olabilecek POINTER_64 değerleri kullanırken dikkatli olun. Derleyici, 32 bit kodda işaretçiyi işarete göre genişletir, işaretçiyi sıfıra göre genişletmez.
OUT parametrelerini kullanırken dikkatli olun.
Örneğin, aşağıdaki gibi tanımlanmış bir işleviniz olduğunu varsayalım:
void func( OUT PULONG *PointerToUlong );Bu işlevi aşağıdaki gibi çağırmayın.
ULONG ul; PULONG lp; func((PULONG *)&ul); lp = (PULONG)ul;Bunun yerine aşağıdaki çağrıyı kullanın.
PULONG lp; func(&lp);Tip dönüştürme ile &ul'nin PULONG* yapılması derleyici hatasını önler, ancak işlev &ul konumundaki belleğe 64 bitlik bir işaretçi değeri yazar. Bu kod 32 bit Windows üzerinde çalışır, ancak 64 bit Windows'ta veri bozulmasına neden olur ve ince, bulunması zor bozulmaya neden olur. Önemli olan: C koduyla oyun oynamayın; basit ve anlaşılır daha iyidir.
Polimorfik arabirimlere dikkat edin.
Çok biçimli veriler için DWORD parametrelerini kabul eden işlevler oluşturmayın. Veriler bir işaretçi veya tam sayı değeri olabilirse, UINT_PTR veya PVOID türünü kullanın.
Örneğin, DWORD değerleri olarak yazılan özel durum parametreleri dizisini kabul eden bir işlev oluşturmayın. Dizi, DWORD_PTR değerlerden oluşan bir dizi olmalıdır. Bu nedenle, dizi öğeleri adresleri veya 32 bit integral değerlerini tutabilir. (Genel kural, özgün tür DWORD ise ve işaretçi genişliği olması gerekiyorsa, bunu DWORD_PTR bir değere dönüştürmesidir. Bu nedenle buna karşılık gelen işaretçi duyarlık türleri vardır.) DWORD, ULONGveya diğer 32 bit türleri polimorfik bir şekilde kullanan kodunuz varsa (yani, parametrenin veya yapı üyesinin bir adresi tutmasını gerçekten istiyorsanız), geçerli türün yerine UINT_PTR kullanın.
Yeni pencere sınıfı işlevlerini kullanın.
İşaretçiler içeren pencere veya sınıf özel verileriniz varsa kodunuzun aşağıdaki yeni işlevleri kullanması gerekir:
- GetClassLongPtr
- GetWindowLongPtr
- SetClassLongPtr
- SetWindowLongPtr
Bu işlevler hem 32 hem de 64 bit Windows'ta kullanılabilir, ancak 64 bit Windows üzerinde gereklidir. Şimdi bu işlevleri kullanarak geçişe hazırlanın.
Ayrıca, 64 bit Windows'taki yeni işlevleri kullanarak sınıf özel verilerindeki işaretçilere veya tanıtıcılara erişmeniz gerekir. Bu durumları bulmanıza yardımcı olmak için, 64 bit derleme sırasında Winuser.h dosyasında aşağıdaki dizinler tanımlanmaz:
- GWL_WNDPROC
- GWL_HINSTANCE
- GWL_HWNDPARENT
- GWL_USERDATA
Bunun yerine, Winuser.h aşağıdaki yeni dizinleri tanımlar:
- GWLP_WNDPROC
- GWLP_HINSTANCE
- GWLP_HWNDPARENT
- GWLP_USERDATA
- GWLP_ID
Örneğin, aşağıdaki kod derlenmez:
SetWindowLong(hWnd, GWL_WNDPROC, (LONG)MyWndProc);Aşağıdaki gibi değiştirilmelidir:
SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)MyWndProc);WNDCLASS yapısının cbWndExtra üyesini ayarlarken, işaretçiler için yeterli alan ayırdığınızdan emin olun. Örneğin, şu anda bir işaretçi değeri için sizeof(DWORD) bayt ayırıyorsanız, bunun yerine sizeof(DWORD_PTR) bayt ayırın.
FIELD_OFFSETkullanarak tüm pencere ve sınıf verilerine erişin.
Sabit kodlanmış uzaklıkları kullanarak pencere verilerine erişmek yaygın bir durumdur. Bu teknik 64 bit Windows'a taşınabilir değildir. Kodunuzu taşınabilir hale getirmek için FIELD_OFFSET makroyu kullanarak pencerenize ve sınıf verilerinize erişin. İkinci işaretçinin 4 uzaklığı olduğunu varsaymayın.
LPARAM, WPARAMve LRESULT türleri platformla boyut değiştirir.
64 bit kod derlenirken, genellikle işaretçileri veya tam sayı türlerini barındırdıkları için bu türler 64 bit'e genişletilir. Bu değerleri DWORD, ULONG, UINT, INT, intveya uzun değerleriyle karıştırmayın. Bu türleri nasıl kullandığınızı inceleyin ve yanlışlıkla değerleri kesmediğinizden emin olun.