Как определить разрядность приложения

В настоящее время в связи с распространением 64-разрядных процессоров и операционных систем, перед разработчиками программного обеспечения часто встаёт вопрос о программном определении его разрядности.

Это может быть вызвано как декоративными причинами («автоматически» показывать разрядность пользователю, например, «Моя Программа 1.0 64-разрядная версия») так и необходимостью задействовать в различных архитектурах различные алгоритмы с целью максимально эффективного использования их особенностей и при этом сохранить единую кодовую базу.

Простейшие способы

В Delphi для того чтобы определить разрядность приложения достаточно получить размер не типизированного указателя с помощью стандартного приёма.

В результате будет возвращён размер не типизированного указателя в байтах. Для перевода в биты достаточно умножить полученный результат на 8. В случае 32-разрядного приложения результат будет равен 4 (после умножения 32). В случае же 64-разядного приложения результат будет равен 8 (после умножения 64).

Для C++ существует аналогичный приём.

Похожий способ есть и в языке C#. Для того чтобы определить разрядность необходимо узнать размер типа IntPtr. Однако этот тип не имеет предопределённого размера и поэтому прямое использование функции sizeof вызовет синтаксическую ошибку.

Вследствие этого необходимо использовать метод SizeOf класса Marshal из пространства имён System.Runtime.InteropServices (это пространство имён должно быть предварительно задействовано с помощью директивы using). В результате реализация для C# выглядит следующим образом:

Конечно, это немного более громоздко, чем в случае Delphi или C++.

Всё эти методы предельно просты и доступны даже для начинающих. Однако все они имеют один общий недостаток. При их использовании в программе компилируются одновременно оба варианта кода (и для 32 и для 64-разрядного приложения). В случае небольших проектов или несущественных отличий в алгоритмах между версиями это может оказаться не критично. В противном случае значительный размер программы будет составлять неиспользуемый код. Это приведёт неоправданному увеличению размеров исполняемого файла программы или файла библиотеки в случае DLL. По этой причине все вышеперечисленные методы для реализации специального кода для конкретной архитектуры по большому счёту не пригодны.

Условная компиляция

К счастью, для этого существует альтернатива в виде директив условной компиляции.

В Delphi имеется стандартный символ условной компиляции WIN32, который обозначает 32-разрядную версию операционной системы Windows. С помощью этого символа и директивы компилятора $IFDEF можно указать, какой код будет компилироваться в случае 32-разрядного приложения, а какой в случае 64-разрядного.

Для наглядности приведём простейший пример:

Если приложение 64-разрядное, то будет показано сообщение с текстом «x64».

В C# ситуация значительно сложнее. .Там нет встроенных символов компиляции соответствующих архитектуре по аналогии с вышеупомянутым WIN32 в Delphi. Но их можно легко создать вручную.

Для этого нужно в свойствах проекта, на вкладке «Построение» в поле «Символы условной компиляции» ввести необходимые символы. Например, «x86»

 

и «x64»,

как показано на скриншотах.

После этого можно воспользоваться вновь созданными символами для того чтобы указать какой именно код для какой архитектуры должен компилироваться.

Для этого следует использовать директиву #if.

В принципе, для решения данной задачи вполне можно обойтись и одним символом. Однако вариант с двумя символами в силу своей большей избирательности обеспечивает лучшее сопровождение кода. Пример приведённый для Delphi проще. Но, в случае его использования на любой платформе отличной от Win32 в файле приложения окажется код предназначенный в том числе для Win64.

Что же касается C++, то ввиду разнообразия компиляторов и различий в их спецификациях конкретное универсальное решение отсутствует. В самом общем случае можно воспользоваться способами, приведёнными для Delphi и C# с поправкой на особенности используемого компилятора.

Ссылки

  1. Условная компиляция в Delphi 7 – Краткое описание условной компиляции в Delphi. Несмотря на то, что оно было написано для 7й версии, до сих пор является актуальным.
  2. $IfDef директива компилятора – Описание директивы $IFDEF.
  3. #if (Справочник по C#) – описание директивы #ifна MSDN.
  4. Условная компиляция C# – Блог неизвестного человека. Небольшая, но в тоже время очень информативная статья по условной компиляции в C#.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *