MS Visual Studio Professional 2013 - C++ компилировать один исполняемый файл для 32-битных и 64-битных операционных систем?

Google подсказал мне, что можно скомпилировать код в один исполняемый файл, который будет работать как 32-разрядный в 32-разрядной ОС и как 64-разрядный в 64-разрядной ОС< /сильный>. Действительно ли исполняемый файл может определить свою разрядность во время выполнения?

В моем случае целевыми системами будут Windows 7 Professional x64 и Windows XP SP3 x86.

Итак, что я читал в различных статьях (я думаю, что были даже ответы на похожие темы на SO), так это то, что нужно перейти к Configuration Manager Soltuion (ПКМ на решение -> Диспетчер конфигурации) и установите для параметра Platform значение Любой процессор.

Теперь во всех этих статьях описывалась установка для более старых версий MSVS или MSVC++, но я думаю, что нет серьезных изменений в Configuration Manager в версии RC 2013 (которую я только что установил).

В раскрывающемся списке Active Solution у меня нет параметра Any CPU, поэтому я следовал этому рецепту , который я нашел на SO. Следование этому небольшому руководству в моем случае не помогло, у меня все еще нет возможности выбрать Any CPU при выполнении шага 5:

  • 5) Убедитесь, что в разделе «Новая платформа» выбран «Любой процессор». Если на шаге 3 не было платформы решения Any CPU, убедитесь, что установлен флажок «Создать новую платформу решений». Затем нажмите ОК.

Мне доступны элементы раскрывающегося списка x64 и ARM (тоже Win32, но он уже добавлен по умолчанию), я не могу выбрать Any CPU.

Добавление целевой платформы x64 и компиляция исполняемого файла работают нормально, программа запускается как 64-битная в Windows 7 x64, но, конечно, ее нельзя запускать на 32-битной машине с Windows XP.

Как установить целевую платформу Any CPU в Microsoft Visual Studio Professional 2013 RC?


person phew    schedule 16.09.2013    source источник


Ответы (5)


Нет, это абсолютно не так. Вам необходимо определить отдельные исполняемые файлы.

Раскрывающийся список «Любой ЦП» позволяет вам устанавливать параметры компилятора для более чем одной платформы (например, процессор _DEBUG для x64 и Win32). На самом деле вы не можете выполнить сборку для этой цели.

person Bathsheba    schedule 16.09.2013
comment
Параметр Any CPU применяется к чистым выходным данным MSIL, а не к собственным компиляциям C++. - person Ben Voigt; 14.12.2013

AnyCPU относится к программам .Net, а не к C++. C++ должен скомпилироваться до родного, либо x86, либо x64. Вы можете создать 64-битную программу и встроить ее в свою 32-битную программу, извлекая ее во время выполнения. Этот метод используется ProcessExplorer.

person Joel Lucsy    schedule 16.09.2013

Возможно, это неверный ответ, но для БОЛЬШИНСТВА вещей запуск 32-битного кода в 64-битной системе работает абсолютно нормально. Конечно, он может работать немного медленнее, но по сравнению с необходимостью иметь дело (и тщательно тестировать) с двумя разными двоичными файлами, если только это не дает значительных преимуществ в производительности в 64-битном режиме (или ваше приложение использует более 2 ГБ памяти), Я бы очень хотел использовать 32-битный режим.

person Mats Petersson    schedule 16.09.2013
comment
Тот же ответ, что я собирался дать. Однако стоит отметить, что уровень WOW64, необходимый для запуска 32-разрядных исполняемых файлов, отсутствует в среде предустановки Windows или в некоторых конфигурациях сервера (возможно, Server Core?) - person Ben Voigt; 14.12.2013
comment
Это действительно Server Core - person Ben Voigt; 14.12.2013

MacOS поддерживает так называемые «толстые двоичные файлы», когда программа компилируется дважды, и обе версии упаковываются в один файл. ОС решает, какую версию запустить.

В винде нет ничего подобного.

person Sebastian Redl    schedule 16.09.2013

Вы можете скомпилировать оболочку .NET (любой процессор) и остальную часть программы как yourprogram86.dll и yourprogram64.dll

[DllImport("yourprogram32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "open")]
public static extern void open32();

[DllImport("yourprogram64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "open")]
public static extern void open64();       

static bool Is64()
{
    //.Net 4.0
    //Environment.Is64BitOperatingSystem

    //.Net 2.0
    return IntPtr.Size == 8;
}

static void open()
{
  if (Is64())
    open64();
  else
    open32();
}
person Tomas Kubes    schedule 30.03.2014