2009-02-13 32 views
27

Hầu hết các chương trình gần đây của tôi đã có trên Windows 32 bit sử dụng C/C++/C#/VB6. Gần đây, khách hàng của tôi đang hỏi liệu mã của tôi có chạy trên Windows 64 bit hay không.Là một lập trình viên, tôi cần phải lo lắng gì khi chuyển sang các cửa sổ 64 bit?

Tôi tự hỏi những tính năng cũ nào tôi có thể đang sử dụng sẽ phá vỡ trên Windows 64 bit? Một số vấn đề trong thế giới thực mà tôi cần phải suy nghĩ và lo lắng là gì?

Rõ ràng, tôi sẽ kiểm tra mã của mình trên hệ điều hành 64 bit, nhưng tôi muốn biết những vấn đề phổ biến cần tìm. Tôi quan tâm nhiều hơn đến các tệp nhị phân hiện có, nhưng tôi mở để nhận xét về những gì cần phải lo lắng khi biên dịch lại (nếu có thể).

EDIT: Đây là lỗi nice list của các lỗi chuyển 64 bit.

+0

Ngôn ngữ nào? Điều này làm cho một sự khác biệt rất lớn :) –

+0

Tôi có rất nhiều mã Win32 trong một số ngôn ngữ: C, C + +, và VB6. Tôi cũng có mã NET trong C# - Tôi không chắc chắn nếu điều đó sẽ có cùng một loại vấn đề. –

+1

Tìm hiểu * Tại sao * có sự cố xảy ra từ 32 bit đến 64 bit. –

Trả lời

5

Có thể dễ dàng di chuyển mã .NET hơn nếu bạn có 100% "loại mã được quản lý an toàn". Bạn chỉ có thể sao chép nó vào nền tảng 64-bit và chạy nó thành công theo CLR 64-bit. Kiểm tra điều này MSDN link khi di chuyển mã Được quản lý 32 bit sang 64 bit.

Btw, hanselman blogged về chủ đề gần đây.

+0

Đó là một mẹo hay, cho mã .NET. –

3

Nếu bạn đang nói về các chương trình 32 bit thì bạn thực tế không có gì phải lo lắng vì Windows 64 sẽ chạy chúng dưới dạng mô phỏng dưới dạng 32 bit. Mọi sự cố xảy ra với các phiên bản Windows trong tương lai (ví dụ: Windows 7) có thể không tương thích thay vì các vấn đề với hệ điều hành 64 bit. Tuy nhiên, nếu mã được quản lý của bạn được biên dịch cho nền tảng đích "Bất kỳ CPU" và bạn thực hiện cuộc gọi vào mã không được quản lý (ví dụ: PInvoke) hoặc phụ thuộc vào các hội đồng khác thì có một số điều cần lưu ý. Scott Hanselman post về CLR x86/x64 bao gồm điều này và là một lời giải thích tốt về CLR trên Win32/64.

Khi phát triển chương trình gốc 64 bit, thì Programming Guide for 64-bit Windows là hướng dẫn tốt. Nó chủ yếu là đi xuống đến con trỏ và kích thước của kiểu dữ liệu :)

0

Từ một góc độ C++/C ....

Một điều rõ ràng là kích thước của một int sẽ trở thành 8 byte thay vì 4 byte . Nếu bất kỳ mã nào của bạn phụ thuộc vào việc bạn có thể nhận được kết quả không mong muốn. Cấu trúc và sự sắp xếp biến có thể thay đổi. Bạn có thể khắc phục nó bằng gói #pragma, nhưng tôi không thành thạo về sắp xếp và đóng gói.

Nếu bạn sử dụng bất kỳ công đoàn nào có int trong đó, hành vi có thể thay đổi.

Nếu bạn đang sử dụng bất kỳ cấu trúc bitfield nào, dựa trên ints, 32 bit phụ có thể gây nhầm lẫn. Các bit dấu sẽ không được nơi bạn nghĩ nó được.

Nếu bạn mã bất kỳ hằng số hex nào và mong đợi các dấu hiệu bị âm, bạn có thể gặp sự cố. Ví dụ 0x8000000 là số âm làm nhật ký hoặc số nguyên 32 bit. 0x80000000 dưới dạng số nguyên trên nền tảng 64 bit là số dương. để trực tiếp thiết lập bit dấu, bạn sẽ phải sử dụng 0x80000000 00000000 (không gian nhúng cho chỉ đọc)

Ngoài ra tôi mong đợi size__t để phát triển một cách thích hợp. Nếu bạn đang thực hiện bất kỳ phân bổ nào dựa trên MAX_INT, chúng sẽ lớn hơn nhiều.

Để tránh các loại dị thường kích thước này, tôi thường gắn liền với thời gian thay vì ints.

+0

Vâng, bạn nên sử dụng một cái gì đó như http://en.wikipedia.org/wiki/Stdint.h để thực sự chỉ định các bit mà bạn muốn. – Calyth

+0

Không int vẫn còn 32 bit trong Win64? – Peter

+0

int vẫn là 32-bit trong Win64 - không rõ ràng như vậy tôi đoán :) –

2

Chương trình 32 bit sẽ chạy tốt trên cửa sổ 64 bit. Miễn là bạn không làm bất kỳ loại trình điều khiển thiết bị của sự phát triển của khóa học.

Nếu bạn biên dịch phần mềm của bạn như một phần mềm 64 bit lần đầu tiên, bạn cần phải chăm sóc sau:

  • một con trỏ là 64 bit rộng, trong khi một int là 32 bit. Không lưu trữ con trỏ trong ints, mã của bạn sẽ phá vỡ.
  • Quy trình 64 bit cần 64 bit DLL. Nếu bạn phụ thuộc vào phần DLL thứ ba, hãy chắc chắn rằng chúng cũng được cung cấp trong 64 bit. Nếu bạn cần giao tiếp giữa quy trình 32 bit và quy trình 64 bit, bạn sẽ cần một số trong nhiều cách khác nhau của IPC trên Windows. Chức năng gọi trực tiếp là hết câu hỏi.
  • Các thư mục hệ thống trên 64 bit Windows khác với Windows 32 bit. Nếu bạn có một số đường dẫn mã hóa cứng, bạn có thể cần phải kiểm tra lại chúng.
+0

Như được ghi nhận bởi những người khác, có rất nhiều điều có thể được thực hiện giả định một kích thước số nguyên nhất định sẽ phá vỡ. Tôi không nghĩ rằng chỉ cần gạt nó ra để nói miễn là bạn không làm bất kỳ trình điều khiển thiết bị nào, bạn sẽ ổn thôi. – Calyth

+0

Tôi chưa thấy ứng dụng 32 bit bị hỏng trên cửa sổ 64 bit - miễn là nó không phải là trình điều khiển thiết bị. Họ chỉ đơn giản là không chạy trên Windows 64 bit. – nusi

+0

Đúc một con trỏ tới một int đã được sử dụng trên rất nhiều dự án và cho rằng các mẫu xấu là nguồn phổ biến của vấn đề 32-> 64 bit. Tôi chưa thấy bất kỳ hình thức sử dụng hợp pháp nào khác của các cấu trúc của các langauges mà OP yêu cầu cho điều đó đáng nói đến. – nusi

0

Giả lập 32 bit có thực sự là bằng chứng đạn không? Tôi đã thấy rằng đăng ký được bố trí một chút khác nhau. Tôi chỉ tự hỏi những gì điển hình không hoạt động ...

Ngoài ra, thư mục C: \ windows \ SYSTEM32 chỉ có thể chứa các tệp DLL 64 bit. Nếu bạn có một DLL 32 bit, bạn cần phải đặt nó trong C: \ windows \ syswow64 \

20

Theo như tôi quan tâm, điều quan trọng nhất về việc chuyển mã C/C++ sang Windows 64 bit là thử nghiệm ứng dụng của bạn với MEM_TOP_DOWN phân bổ kích hoạt (AllocationPreference giá trị registry) như mô tả trong 4-Gigabyte Tuning:

buộc phân bổ để phân bổ từ các địa chỉ cao hơn trước khi địa chỉ thấp hơn cho mục đích thử nghiệm, xác định MEM_TOP_DOWN khi gọi VirtualAlloc hoặc đặt sau giá trị đăng ký 0x100000:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference

Khi nào thì vấn đề này?

  • Nếu bạn hiện có EXEs 32-bit được xây dựng với các tùy chọn liên kết /LARGEADDRESSAWARE MSVC (hoặc có cờ IMAGE_FILE_LARGE_ADDRESS_AWARE đặt trong tiêu đề PE của họ thông qua các phương tiện khác, chẳng hạn như editbin.exe), sau đó họ có được một đầy đủ 4 GB không gian địa chỉ ảo trong Windows 64 bit và bạn phải kiểm tra chúng bằng bộ giá trị đăng ký AllocationPreference.
  • Nếu bạn có các tệp DLL 32 bit hiện có có thể được tải bằng các EXE nhận biết địa chỉ lớn, bạn phải kiểm tra chúng bằng bộ giá trị đăng ký AllocationPreference.
  • Nếu bạn biên dịch lại mã C/C++ của bạn thành EXE 64 bit hoặc DLL, bạn phải kiểm tra nó với bộ giá trị đăng ký AllocationPreference.

Nếu C/C++ ứng dụng rơi vào một trong ba loại và bạn không thử nghiệm với MEM_TOP_DOWN phân bổ, kiểm tra là rất khó để nắm bắt bất kỳ lỗi con trỏ cắt ngắn/signedness trong mã của bạn.

Điều quan trọng thứ hai, nếu bạn sử dụng MSVC và bạn đang biên dịch lại C/C++ mã cho 64-bit, là để sử dụng tùy chọn /Wp64 trình biên dịch cho bạn 64-bit build:

  • Điều này sẽ làm cho trình biên dịch phát ra cảnh báo cho các dự đoán cắt xén con trỏ hoặc mở rộng các kiểu tích phân nhỏ hơn thành con trỏ (ngay cả khi sử dụng reinterpret_cast hoặc một kiểu đúc C) cũng như một số vấn đề khác về cổng 64 bit.
  • Có, documentation nói rằng thay vì biên dịch với /Wp64, bạn nên sử dụng trình biên dịch nhắm mục tiêu nền tảng 64 bit, nhưng chỉ riêng điều đó sẽ không bắt gặp sự cố cắt ngắn/mở rộng con trỏ tại thời gian biên dịch. Sử dụng trình biên dịch nhắm mục tiêu 642 bit cho phép tùy chọn biên dịch /Wp64 cho bản dựng 64 bit sẽ bắt gặp nhiều vấn đề về cắt bớt/mở rộng con trỏ tại thời gian biên dịch và điều này sẽ giúp bạn tiết kiệm thời gian trong thời gian dài.
  • Thật không may, với MSVC 2008, điều này cũng sẽ tạo ra "cảnh báo dòng lệnh" cho mỗi đơn vị dịch nói rằng tùy chọn /Wp64 không còn được dùng nữa. Tôi có thể thấy lý do tại sao tùy chọn không được dùng cho các bản dựng 32 bit (nơi mà nó là một bản hack độc hại yêu cầu chú thích nhiều typedef của bạn), nhưng thật không may là nó cũng bị phản đối cho các bản dựng 64 bit (nơi nó thực sự hữu ích).
+0

Tôi đồng ý rằng việc buộc phân bổ ở trên dòng 4 GB thực sự quan trọng, nhưng việc sử dụng 'MEM_TOP_DOWN' có thể làm cho phân bổ thực sự chậm nếu bạn thực hiện rất nhiều. Một cách khác để buộc phân bổ có địa chỉ "cao" là đặt trước tất cả địa chỉ "thấp". Đây là một kỹ thuật tôi đã sử dụng: http://stackoverflow.com/a/29220631/1339280 – shoelzer

1

Nếu bạn làm tiêm DLL cho bất kỳ lý do bạn sẽ gặp khó khăn.

Các vấn đề liên quan