Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Как сделать код совместимым с Win64





 

Вероятно, при преобразовании Win32-кода в x64-код больше всего усилий понадобится для того, чтобы сохранить корректность ваших определений типов. Выше говорилось о системе типов в Win64? Используя Windows-типы, определенные через typedef в заголовочных файлах Windows, а не "родные" для компилятора C++ типы (int, long и др.), мы упростим себе написание чистого Win32-кода, способного работать на платформе x64.

Вероятно, наиболее частая и легко устранимая ошибка, которую можно встретить при переносе кода, вызвана предположением о том, что значение указателя может быть сохранено или перенесено в 32-разрядном типе вроде int, long или даже DWORD. Но вся штука в том, что указатели в Win32 и Win64 имеют разные размеры, а целочисленные типы остались прежней длины.

Здесь помогают типы _PTR, определенные в заголовочных файлах Windows. Такие типы, как DWORD_PTR, INT_PTR и LONG_PTR, позволяют объявлять переменные целочисленного типа, которые всегда имеют достаточный размер для хранения указателя на целевой платформе. Например, переменная, определенная как тип DWORD_PTR, является 32-битной целой при компиляции для Win32 и 64-битной при компиляции для Win64. Немного практики, и использование таких переменных станет вашей второй натурой: объявляя какой-либо тип, вы всегда будете спрашивать себя, нужен здесь DWORD или DWORD_PTR?

Возможны ситуации, где надо точно указывать, сколько именно байтов следует отвести под целый тип. На такие случаи в тех же заголовочных файлах (Basetsd.h и др.), где определяются DWORD_PTR и прочие типы, предлагаются определения целых специфической длины, например INT32, INT64, INT16, UINT32 и DWORD64.

Еще одна проблема, связанная с различиями в размерах типов, относится к форматированию вывода printf и sprintf. Вот я раньше часто грешил конструкциями %X или %08X при форматировании значений указателей и был строго наказан за это при запуске подобного кода в x64-системе. Правильный способ - использование %p, при котором автоматически учитывается размер указателя на целевой платформе. Кроме того, printf и sprintf поддерживают префикс I для типов, размер которых зависит от платформы. Скажем, для вывода значения переменной UINT_PTR можно было бы использовать %Iu. Если же вы точно знаете, что переменная всегда будет 64-битной знаковой, то могли бы указать %I64d.

Вычистив ошибки, вызванные определениями типов, неподходящими для Win64, вы все равно можете остаться с кодом, который работает только на платформе x86. Тогда, вероятно, лучше пойти по простейшему пути и написать две версии функции: одну - для Win32, другую - для x64. И здесь нам очень пригодится набор макросов препроцессора:

 

M_IX86_M_AMD64_WIN64

Правильное использование макросов препроцессора очень важно для написания корректного кросс-платформенного кода. Макросы _M_IX86 и _M_AMD64 применяются только при компиляции под определенную платформу, а _WIN64 - при компиляции для любой 64-разрядной версии Windows, в том числе выпуска для процессоров Itanium.

Пытаясь применить макрос препроцессора, хорошенько подумайте о том, чего вы добиваетесь. Например, действительно ли ваш код специфичен только для процессоров x64? Если да, пишите:

 

#ifdef _M_AMD64

С другой стороны, если тот же код мог бы работать и на x64, и на Itanium, лучше сделать так:

 

#ifdef _WIN64

Для себя я принял полезное правило при использовании любого из этих макросов: всегда создавать явные варианты #else (подчеркиваю, явные!), чтобы можно было быстро понять, не пропущено ли что-то. Для примера возьмем плохо написанный код:

 

#ifdef _M_AMD64// Здесь находится x64-код#else// Здесь находится x86-код#endif

Что будет, если я теперь скомпилирую его для третьей процессорной архитектуры? Сам того не желая, я скомпилирую x86-код. Гораздо лучше переделать предыдущий код примерно так:

 

#ifdef _M_AMD64// Здесь находится x64-код#elif defined (_M_IX86)// Здесь находится x86-код#else#error!!! Нужно написать код для этой архитектуры#endif

Одна из частей моего Win32-кода, которую удалось перенести на платформу x64 лишь с большим трудом, - подставляемый (inline) ассемблерный код, не поддерживаемый Visual C++ для x64. Но не бойтесь, любители ассемблера. Существует 64-разрядный MASM (ML64.exe); его вместе с документацией можно получить через MSDN. ML64.exe и другие инструменты для x64 (в том числе CL.EXE и LINK.EXE) доступны из командной строки. Чтобы настроить нужные переменные окружения, достаточно запустить файл VCVARS64.BAT.

Date: 2015-09-18; view: 370; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.006 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию