Подтвердить что ты не робот

Какие функции выполняет _WinMainCRTStartup?

Это часть серии по крайней мере двух тесно связанных, но разных вопросов. Надеюсь, я поступаю правильно, задавая их отдельно.

Я пытаюсь заставить мое приложение Visual С++ 2008 работать без библиотеки времени выполнения C. Это приложение Win32 GUI без MFC или других причудливых вещей, просто обычный API Windows.

Итак, я установил свойства проекта → Конфигурация → C/С++ → Дополнительно → Опустить имена библиотек по умолчанию в Да (флаг компилятора /Zl) и перестроен.

Затем компоновщик жалуется на неразрешенный внешний _WinMainCRTStartup. Достаточно справедливо, я могу сказать компоновщику использовать другую точку входа, скажем MyStartup. Из того, что я собираю в Интернете, _WinMainCRTStartup выполняет некоторые операции инициализации, и я, вероятно, хочу, чтобы MyStartup выполнял подмножество этого.

Итак, мой вопрос: Какие функции выполняет _WinMainCRTStartup, и какие из них можно опустить, если я не использую CRT?

Если вы хорошо осведомлены об этом, пожалуйста, посмотрите мой другой вопрос. Спасибо!

Кроме того: почему я хочу сделать это в первую очередь?

  • В моем приложении явно не используются функции CRT.
  • Мне нравятся скудные и средние приложения.
  • Это научит меня чему-то новому.
4b9b3361

Ответ 1

Точка входа CRT делает следующее (этот список не завершен):

  • Инициализирует глобальное состояние, необходимое для ЭЛТ. Если это не сделано, вы не можете использовать какие-либо функции или состояние, предоставленные ЭЛТ.
  • Инициализирует какое-то глобальное состояние, которое используется компилятором. Проверки времени выполнения, такие как cookie безопасности, используемые /GS, определенно выделяются здесь. Однако вы можете вызвать __ security_init_cookie. Возможно, вам придется добавить другой код для других проверок времени выполнения.
  • Вызывает конструкторы на объектах С++. Если вы пишете код на С++, вам может понадобиться подражать этому.
  • Извлекает командную строку и запускает информацию, предоставляемую ОС, и передает ее на ваш основной. По умолчанию, никакие параметры не передаются в точку входа программы операционной системой - все они подтверждены ЭЛТ.

Исходный код CRT доступен в Visual Studio, и вы можете пройти через точку входа CRT в отладчике и узнать, что именно он делает.

Ответ 2

Настоящая программа Win32, написанная на C (не С++), вообще не нуждается в инициализации, поэтому вы можете запустить свой проект с помощью WinMainCRTStartup() вместо WinMain (HINSTANCE,...).

Также возможно, но немного сложнее писать консольные программы как настоящие приложения Win32; по умолчанию имя точки входа _mainCRTStartup().

Отключите все дополнительные функции генерации кода, такие как проверки стека, проверки массивов и т.д. Отладка по-прежнему возможна.

Инициализация

Иногда вам нужен первый параметр HINSTANCE. Для Win32 (кроме Win32) он привязан к (HINSTANCE) 0x400000.

Параметр nCmdShow всегда SW_SHOWDEFAULT.

При необходимости загрузите командную строку с помощью GetCommandLine().

Расторжение

Когда ваша программа порождает потоки, например. вызывая GetOpenFileName(), возврат из WinMainCRTStartup() с ключевым словом return приведет к зависанию вашей программы - используйте ExitProcess() > вместо этого.

Предостережения

Вы столкнетесь со значительными проблемами, если:

  • с использованием фреймов стека (то есть локальных переменных) размером более 4 Кбайт (для каждой функции)
  • с использованием арифметики с плавающей точкой (например, float- > int conversion)
  • с использованием 64-разрядных целых чисел на 32-разрядных машинах (операции умножения, бит-сдвиг)
  • с использованием С++ new, удалить и статических объектов с конструкторами без нуля-вне всех
  • используя стандартные библиотечные функции, например fopen(), printf()

Устранение неполадок

Существует стандартная библиотека C, доступная во всех системах Windows (начиная с Windows 95), MSVCRT.DLL.

Чтобы использовать его, импортируйте свои точки входа, например. используя мой msvcrt-light.lib (google для него). Но есть еще некоторые оговорки, особенно при использовании компиляторов, более новых, чем MSVC6:

  • фреймы стека по-прежнему ограничены 4 Кбайтами
  • _ftol_sse или _ftol2_sse должен быть перенаправлен на _ftol
  • _iob_func должен быть перенаправлен на _iob

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

Ответ 3

Старый вопрос, но ответы либо неверны, либо сосредоточены на одной конкретной проблеме.

Существует ряд функций C и С++, которые просто не будут доступны в Windows (или большинстве операционных систем, если на то пошло), если программы действительно начались с main/WinMain.

Возьмем этот простой пример:

class my_class
{
public:
    my_class() { m_val = 5; }
    int my_func(){ return m_val }
private:
    int m_val;
}

my_class g_class;

int main(int argc, char **argv)
{
     return g_class.my_func();
}

чтобы эта программа функционировала должным образом, конструктор для my_class должен быть вызван до main. Если программа началась точно в главном, для нее потребуется компилятор (обратите внимание: GCC делает это в некоторых случаях), чтобы вставить вызов функции в самом начале main. Вместо этого в большинстве ОС и в большинстве случаев другая функция создает g_class, а затем вызывает main (в Windows это либо mainCRTStartup, либо WinMainCRTStartup; в большинстве других ОС, к которым я привык, используется функция _start).

Иными словами, С++ и даже C должны выполняться до или после работы main. Как stdin и stdout (std:: cin и std:: cout) можно использовать, как только начнется main? Как работает atexit?

Стандарт C требует, чтобы стандартная библиотека имела API-интерфейс, подобный POSIX, который в Windows должен быть "установлен" перед main().

В большинстве ОС нет системной кучи; среда выполнения C реализует свою собственную кучу (время выполнения Microsoft C просто обертывает функции Kernel32 Heap).

Даже аргументы, переданные main, argc и argv, должны каким-то образом получить от системы.

Возможно, вы захотите взглянуть на статьи Мэтта Пьетрика (старинного) о реализации его собственной среды выполнения C, чтобы узнать, как это работает с Windows + MSVC (примечание: MinGW и Cygwin реализуют определенные вещи по-разному, но фактически возвращаются к MSVCRT для большинства вещей): http://msdn.microsoft.com/en-us/library/bb985746.aspx