Сбой приложения при компиляции в / SUBSYSTEM: WINDOWS с / ENTRY: основной и / MT библиотекой времени выполнения - PullRequest
0 голосов
/ 28 апреля 2019

Я пытаюсь создать простое приложение для Windows, но на основе точки входа main (), так как мне нужно скомпилировать его на других платформах.

Я нашел конкретные директивы, чтобы сделать это с Visual Studio, но, похоже, он работает при компиляции библиотеки времени выполнения / MD, но вылетает при использовании /MT.

Вот полный код для воспроизведения сбоя, он каждый раз дает сбой. ==> Просто создайте пустой проект с файлом main.cpp и установите: Projet -> Свойства -> C / C ++ -> Генерация кода -> Библиотека времени выполнения -> / MT

#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
#pragma comment(linker, "/ENTRY:main")
#pragma comment(linker, "/INCLUDE:mainCRTStartup")

int main(int argc, char** argv)
{

    int* a = new int;
    delete a;

    return 0;
}

Это вызывает следующее исключение:

ntdll.dll!RtlpWaitOnCriticalSection()   Inconnu
ntdll.dll!RtlpEnterCriticalSectionContended()   Inconnu
ntdll.dll!RtlEnterCriticalSection() Inconnu
Application.exe!__acrt_lock(__acrt_lock_id _Lock) Ligne 55  C++
Application.exe!heap_alloc_dbg_internal(const unsigned __int64 size, const int block_use, const char * const file_name, const int line_number) Ligne 309    C++
Application.exe!heap_alloc_dbg(const unsigned __int64 size, const int block_use, const char * const file_name, const int line_number) Ligne 450 C++
Application.exe!_malloc_dbg(unsigned __int64 size, int block_use, const char * file_name, int line_number) Ligne 496    C++
Application.exe!malloc(unsigned __int64 size) Ligne 27  C++
[Code externe]  
Application.exe!main(int argc, char * * argv) Ligne 9   C++
[Code externe]  

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

#pragma comment(linker, "/SUBSYSTEM:WINDOWS")

int main(int argc, char** argv)
{

    int* a = new int;
    delete a;

    return 0;
}

INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow)
{
    return main(1, reinterpret_cast<char**>(&lpCmdLine));
}

Я хочу компилировать без внешней зависимости MSVCRT, поэтому я устанавливаю режим / MT.

У вас есть предложения? Я работаю над этой проблемой в течение многих дней ....

Ответы [ 2 ]

1 голос
/ 28 апреля 2019

Точка входа не является main или WinMain, это функция в библиотеках MS, которая инициализирует CRT. Ваш main пример не работает, потому что вы обойдете эту инициализацию. Пример WinMain работает, потому что эта инициализация происходит до того, как WinMain начинает выполнение. При связывании с версией DLL среды выполнения эта инициализация происходит при загрузке DLL.

Вы должны указать /SUBSYSTEM:CONSOLE или просто оставить его выключенным и позволить компоновщику определить правильную подсистему.

0 голосов
/ 28 апреля 2019

Установите опцию компоновщика на CONSOLE (подробнее здесь ) и все. Если вам не нужна консоль, отсоединитесь от нее, используя FreeConsole .

Другое простое решение - WinMain вызывать пользовательский main2 в Windows и основной вызов - тот же main2 на других платформах.

#ifdef _WIN32
int __stdcall WinMain(...) { return main2(); }
#else
int main(...) { return main2(); }
#endif
...