2009-02-13 14 views
27

Większość mojego ostatniego programowania była w 32-bitowym systemie Windows przy użyciu C/C++/C#/VB6. Ostatnio moi klienci pytają, czy mój kod będzie działał w 64-bitowym systemie Windows.Jako programista, o co muszę się martwić podczas przechodzenia do 64-bitowych okien?

Zastanawiam się, jakie starsze funkcje, których mogę używać, będą łamać się w 64-bitowym systemie Windows? Jakie są problemy natury realnej, o których muszę się martwić?

Oczywiście testuję mój kod w 64-bitowym systemie operacyjnym, ale chciałbym wiedzieć, jakie typowe problemy należy szukać. Bardziej interesuję się istniejącymi binariami, ale jestem otwarty na komentarze dotyczące tego, o co się martwić, gdy rekompilujemy (jeśli to możliwe).

EDYCJA: Oto nice list z 64-bitowych błędów portowania.

+0

Jaki język? To robi wielką różnicę :) –

+0

Mam wiele kodu Win32 w kilku językach: C, C++ i VB6. Mam również kod .NET w języku C# - Nie jestem pewien, czy miałoby to ten sam rodzaj problemów. –

+1

Dowiedz się * Dlaczego * wystąpił problem polegający na przechodzeniu z 32 do 64 bitów. –

Odpowiedz

5

Migracja kodu .NET może być łatwiejsza, jeśli posiadasz 100% "bezpieczny kod zarządzany typu". Można po prostu skopiować go na platformę 64-bitową i pomyślnie uruchomić w 64-bitowym środowisku CLR. Sprawdź ten MSDN link podczas migracji 32-bitowego kodu zarządzanego na 64-bitowy.

Btw, hanselman blogged o temacie ostatnio.

+0

To dobra wskazówka dla kodu .NET. –

3

Jeśli mówisz o programach 32-bitowych, nie masz praktycznie powodów do obaw, ponieważ system Windows 64 będzie je emulował jako 32-bitowy. Wszelkie problemy z przyszłymi wersjami systemu Windows (np. Windows 7) mogą być raczej niekompatybilnością niż problemami z 64-bitowym systemem operacyjnym.

Jeśli jednak zarządzany kod jest kompilowany dla platformy docelowej "Dowolny procesor", a połączenia są wywoływane w kodzie niezarządzanym (np. PInvoke) lub zależą od innych złożeń, należy pamiętać o kilku rzeczach. Scott Hanselman o numerze post o CLR x86/x64 obejmuje to i jest dobrym wytłumaczeniem CLR na Win32/64.

Podczas opracowywania 64-bitowych programów natywnych dobrym pomysłem jest Programming Guide for 64-bit Windows. To w dużej mierze sprowadza się do wskaźników i wielkości typy danych :)

0

Z perspektywy C/C++ ....

Oczywistą rzeczą jest to, że rozmiar int będzie 8 bajtów zamiast 4 bajty . Jeśli którykolwiek z twoich kodów jest zależny od tego, możesz uzyskać nieoczekiwane wyniki. Struktury i zmienne dopasowania mogą się zmieniać. Możesz go pokonać za pomocą pakietu #pragma, ale nie jestem zbyt biegły w dopasowywaniu i pakowaniu.

Jeśli użyjesz w nich związków z int, zachowanie może się zmienić.

Jeśli korzystasz z dowolnych struktur bitfield, na podstawie ints dodatkowe 32 bity mogą powodować zamieszanie. Bit znaku nie będzie tam, gdzie myślałeś, że to jest.

Jeśli utworzysz jakieś stałe heksadecymalne i spodziewasz się, że znaki będą ujemne, możesz mieć problemy. Przykład 0x8000000 jest liczbą ujemną jako log lub 32-bitową liczbą całkowitą. 0x80000000 jako liczba całkowita na 64-bitowej platformie jest liczbą dodatnią. aby bezpośrednio ustawić bit znaku, musiałbyś użyć 0x80000000 00000000 (przestrzeń wbudowana tylko dla czytelności)

Również oczekuję, że rozmiar odpowiednio wzrośnie. Jeśli robisz alokacje oparte na MAX_INT, będą one znacznie większe.

Aby uniknąć tego typu anomalii wielkości, zwykle trzymam się długich zamiast ints.

+0

Cóż, powinieneś użyć czegoś takiego jak http://en.wikipedia.org/wiki/Stdint.h, aby faktycznie określić bity, które chcesz. – Calyth

+0

Czy nie jest int nadal 32 bity w Win64? – Peter

+0

int jest nadal 32-bitowe w Win64 - nie tak oczywiste, jak sądzę :) –

2

Programy 32-bitowe będą działały poprawnie w oknach 64-bitowych. Tak długo, jak nie robisz żadnego rodzaju programowania sterowników urządzeń.

Jeśli skompilować oprogramowanie jako oprogramowanie 64 bit po raz pierwszy, trzeba zadbać o następujące elementy:

  • wskaźnik wynosi 64 bitowe, natomiast int jest 32-bitowy. Nie przechowuj wskaźników w int, twój kod się zepsuje.
  • Proces 64-bitowy wymaga 64-bitowych bibliotek DLL. Jeśli polegasz na bibliotekach DLL trzeciej części, upewnij się, że są one również dostępne w wersji 64-bitowej. Jeśli potrzebujesz komunikacji między procesem 32-bitowym a procesem 64-bitowym, będziesz potrzebował wielu różnych sposobów IPC w Windows. Wywołanie funkcji bezpośrednio nie wchodzi w grę.
  • Katalogi systemowe w 64-bitowych systemach Windows są inne niż w 32-bitowym systemie Windows. Jeśli masz trochę zakodowanych ścieżek, możesz potrzebować ich ponownie.
+0

Jak zauważyli inni, istnieje wiele innych rzeczy, które można zrobić, zakładając pewną liczbę całkowitą, która mogłaby się zepsuć. Nie sądzę, że dobrze jest po prostu odświeżyć to stwierdzenie, o ile nie robisz żadnego sterownika urządzenia, wszystko byłoby w porządku. – Calyth

+0

Muszę jeszcze zobaczyć 32-bitową aplikację łamiącą się w oknach 64-bitowych - o ile nie jest to sterownik urządzenia. Po prostu nie działają w 64-bitowym systemie Windows. – nusi

+0

Rzucanie wskaźnikiem na int zostało użyte na tylu projektach i prawdopodobnie złych próbkach, że jest to wspólne źródło problemu 32-> 64-bitowego. Nie widziałem jeszcze żadnego innego legalnego użycia konstrukcji językowych, o które prosi się OP, o których warto wspomnieć. – nusi

0

Czy 32-bitowa emulacja jest naprawdę skuteczna? Widziałem, że rejestr jest trochę inaczej sformułowany. Zastanawiam się, jakie typowe rzeczy nie działają ...

Ponadto katalog C: \ windows \ SYSTEM32 może zawierać tylko 64-bitowe biblioteki DLL. Jeśli masz 32-bitową bibliotekę DLL, musisz umieścić ją w C: \ windows \ syswow64 \

20

O ile mi wiadomo, najważniejszą rzeczą jest przeniesienie kodu C/C++ do 64-bitowego systemu Windows jest przetestować aplikację z MEM_TOP_DOWN alokacji włączona (AllocationPreference wartość rejestru) jak opisano w 4-Gigabyte Tuning:

aby wymusić alokacje przydzielić z wyższych adresów przed niższych adresów dla celów testowych, określ MEM_TOP_DOWN dzwoniąc VirtualAlloc lub ustawić następujące wartości rejestru do 0x100000:

Kiedy to ma znaczenie?

  • Jeśli obecne 32-bitowych exe, które zostały zbudowane z opcją łącznika /LARGEADDRESSAWARE MSVC (lub które posiadają flagę IMAGE_FILE_LARGE_ADDRESS_AWARE ustawione w swoich nagłówkach PE za pomocą innych środków, takich jak editbin.exe), potem uzyskać pełny 4 GB wirtualnej przestrzeni adresowej w 64-bitowym systemie Windows i należy przetestować je za pomocą zestawu wartości rejestru AllocationPreference.
  • Jeśli posiadasz 32-bitowe biblioteki DLL, które mogą być ładowane przez pliki EXE z dużymi adresami, musisz je przetestować za pomocą zestawu wartości rejestru AllocationPreference.
  • Jeśli przekompilujesz kod C/C++ do 64-bitowego pliku EXE lub DLL, musisz przetestować go za pomocą zestawu wartości rejestru AllocationPreference.

Jeśli C/C++ aplikacja należy do jednej z tych trzech kategorii i nie test z MEM_TOP_DOWN przydziałów, testowanie jest bardzo mało prawdopodobne, aby złapać jakieś błędy wskaźnik obcięcia/signedness w kodzie.

Drugą najważniejszą rzeczą, jeśli używasz MSVC i są rekompilacji kodu C/C++ dla 64-bitowych, jest należy wybrać opcję /Wp64 kompilatora dla 64-bitowy build:

  • Spowoduje to, że kompilator będzie wysyłać ostrzeżenia dla grup danych, które obcinają wskaźniki lub rozszerzają mniejsze typy całkowe na wskaźniki (nawet gdy jest używany reinterpret_cast lub rzutowanie w stylu C), a także kilka innych problemów z 64-bitowym portowaniem.
  • Tak, mówi, że zamiast kompilować z /Wp64 powinieneś użyć kompilatora, który celuje w platformę 64-bitową, ale to samo nie będzie wychwytywać problemów z obcięciem/rozszerzeniem wskaźnika w czasie kompilacji. Korzystanie z kompilatora, który kieruje 64-bitowy i włączeniu opcji /Wp64 kompilatora dla kompilacji 64-bitowej złapie wiele problemów wskaźnik obcięcie/rozszerzenie w czasie kompilacji, a to pozwoli Ci zaoszczędzić czas na dłuższą metę.
  • Niestety z MSVC 2008, to będzie też produkować „ostrzeżenie wiersza komend” dla każdej jednostki tłumaczeniowej mówiąc, że opcja /Wp64 jest przestarzała. Rozumiem, dlaczego ta opcja jest przestarzała w przypadku wersji 32-bitowych (gdzie jest złym hackiem, który wymaga opisu wielu typedefów), ale niefortunne jest to, że jest ona również przestarzała w przypadku 64-bitowych buildów (gdzie w rzeczywistości jest przydatna).
+0

Zgadzam się, że wymuszanie alokacji powyżej linii 4 GB jest naprawdę ważne, ale użycie 'MEM_TOP_DOWN' może bardzo spowolnić alokacje, jeśli wykonasz je bardzo dużo. Innym sposobem na wymuszenie alokacji adresów "wysokich" jest zarezerwowanie wszystkich "niskich" adresów. Oto jedna z zastosowanych technik: http://stackoverflow.com/a/29220631/1339280 – shoelzer

1

Jeśli zrobić zastrzyk DLL z jakiegokolwiek powodu będziesz miał kłopoty.