Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Det är enkelt att portera koden för kompilering för både 32- och 64-bitars Microsoft Windows. Du behöver bara följa några enkla regler om typomvandling av pekare och använda de nya datatyperna i din kod. Reglerna för pekarmanipulering är följande.
Kasta inte pekare till int, long, ULONGeller DWORD.
Om du måste kasta en pekare för att testa vissa bitar, ange eller rensa bitar eller på annat sätt ändra innehållet använder du UINT_PTR eller INT_PTR typ. Dessa typer är integrerade typer som skalas till storleken på en pekare för både 32- och 64-bitars Windows (till exempel ULONG- för 32-bitars Windows och _int64 för 64-bitars Windows). Anta till exempel att du porterar följande kod:
ImageBase = (PVOID)((ULONG)ImageBase | 1);
Som en del av portningsprocessen ändrar du koden enligt följande:
ImageBase = (PVOID)((ULONG_PTR)ImageBase | 1);
Använd UINT_PTR och INT_PTR när det är lämpligt (och om du är osäker på om de krävs, finns det ingen skada i att använda dem för det fallet). Lägg inte pekarna till typerna ULONG, LONG, INT, UINTeller DWORD.
Observera att HANDLE- definieras som ett void*, så att typecasting av ett HANDLE--värde till ett ULONG- värde för att testa, ange eller rensa 2 bitar i låg ordning är ett fel i 64-bitars Windows.
Använd funktionen PtrToLong eller PtrToUlong för att trunkera pekare.
Om du måste trunkera en pekare till ett 32-bitarsvärde använder du funktionen PtrToLong eller PtrToUlong (definierad i Basetsd.h). Dessa funktioner inaktiverar trunkeringsvarningen för pekare under hela anropet.
Använd dessa funktioner noggrant. När du har konverterat en pekarvariabel med någon av dessa funktioner ska du aldrig använda den som pekare igen. Dessa funktioner trunkerar de övre 32 bitarna av en adress, som vanligtvis behövs för att komma åt minnet som ursprungligen refererades av pekaren. Om du använder dessa funktioner utan noggrant övervägande resulterar det i bräcklig kod.
Var försiktig när du använder POINTER_32 värden i kod som kan kompileras som 64-bitarskod. Kompilatorn teckenutökar pekaren när den tilldelas en inbyggd pekare i 64-bitarskod, inte nollutökar pekaren.
Var försiktig när du använder POINTER_64 värden i kod som kan kompileras som 32-bitarskod. Kompilatorn signerar och utökar pekaren i 32-bitarskod, inte nollförläng pekaren.
Var försiktig med att använda OUT-parametrar.
Anta till exempel att du har en funktion som definierats på följande sätt:
void func( OUT PULONG *PointerToUlong );
Anropa inte den här funktionen på följande sätt.
ULONG ul; PULONG lp; func((PULONG *)&ul); lp = (PULONG)ul;
Använd i stället följande anrop.
PULONG lp; func(&lp);
Typecasting &ul to PULONG* förhindrar ett kompilatorfel, men funktionen skriver ett 64-bitars pekarvärde i minnet på &ul. Den här koden fungerar på 32-bitars Windows, men kommer att orsaka skadade data i 64-bitars Windows och det kommer att vara diskret, svår att hitta skador. Slutsats: Lura inte med C-koden – enkelt och rakt är bättre.
Var försiktig med polymorfa gränssnitt.
Skapa inte funktioner som accepterar DWORD- parametrar för polymorfa data. Om data kan vara en pekare eller ett integralt värde ska du använda typen UINT_PTR eller PVOID-.
Skapa till exempel inte en funktion som accepterar en matris med undantagsparametrar som anges som DWORD- värden. Matrisen ska vara en matris med DWORD_PTR värden. Därför kan matriselementen innehålla adresser eller 32-bitars integralvärden. (Den allmänna regeln är att om den ursprungliga typen är DWORD- och den måste vara pekarbredd, konverterar du den till ett DWORD_PTR värde. Det är därför det finns motsvarande typer av pekarprecision.) Om du har kod som använder DWORD-, ULONG-eller andra 32-bitarstyper på ett polymorft sätt (dvs. du verkligen vill att parametern eller strukturmedlemmen ska innehålla en adress), använder du UINT_PTR i stället för den aktuella typen.
Använd de nya fönsterklassfunktionerna.
Om du har privata data för fönster eller klasser som innehåller pekare måste koden använda följande nya funktioner:
Dessa funktioner kan användas i både 32- och 64-bitars Windows, men de krävs i 64-bitars Windows. Förbered för övergången med hjälp av dessa funktioner nu.
Dessutom måste du komma åt pekare eller handtag i privata klassdata med hjälp av de nya funktionerna på 64-bitars Windows. För att hjälpa dig att hitta dessa fall definieras inte följande index i Winuser.h under en 64-bitars kompilering:
- GWL_WNDPROC
- GWL_HINSTANCE
- GWL_HWNDPARENT
- GWL_USERDATA
I stället definierar Winuser.h följande nya index:
- GWLP_WNDPROC
- GWLP_HINSTANCE
- GWLP_HWNDPARENT
- GWLP_USERDATA
- GWLP_ID
Följande kod kompileras till exempel inte:
SetWindowLong(hWnd, GWL_WNDPROC, (LONG)MyWndProc);
Den bör ändras på följande sätt:
SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)MyWndProc);
När du ställer in medlemmen cbWndExtra i WNDCLASS--strukturen måste du reservera tillräckligt med utrymme för pekare. Om du till exempel för närvarande reserverar storleken av (DWORD) byte för ett pekarvärde, ska du reservera storleken av (DWORD_PTR) byte.
Få åtkomst till alla fönster- och klassdata med hjälp av FIELD_OFFSET.
Det är vanligt att komma åt fönsterdata med hårdkodade positioner. Den här tekniken är inte portabel för 64-bitars Windows. Om du vill göra koden portabel öppnar du fönstret och klassdata med hjälp av makrot FIELD_OFFSET. Anta inte att den andra pekaren har en förskjutning på 4.
LPARAM, WPARAMoch LRESULT typer ändrar storlek med plattformen.
När du kompilerar 64-bitars kod expanderas dessa typer till 64 bitar, eftersom de vanligtvis innehåller pekare eller integraltyper. Blanda inte dessa värden med DWORD, ULONG, UINT, INT, inteller långa värden. Granska hur du använder dessa typer och se till att du inte oavsiktligt förkortar värden.