Как вручную инициализировать среду выполнения c в exe?
Я пытаюсь предоставить собственную точку входа в исполняемый файл Visual C++, используя переключатель компоновщика "/entry". Соответствующая документация Microsoft содержит некоторые подробности о том, как вручную инициализировать среду выполнения c в dll, но я не могу понять, как инициализировать ее в моем exe-файле. Лучшее, что у меня есть, - это то, что мне нужно вызывать _CRT_init, но я не знаю, является ли это функцией или макросом, или где она может быть определена, а Visual Studio (и msbuild) не распознает идентификатор, поэтому никаких намеков там нет.
Обоснованием здесь является то, что я пытаюсь выполнить модульное тестирование с помощью Google Test, исполняемого файла, и он не будет связываться, потому что main() конфликтует. Два подхода, упомянутые в FAQ по GTest, на самом деле не могут быть обобщены и потребуют значительной доработки для реализации около 30 устаревших исполняемых файлов. Переименование main() каждого модульного тестового приложения кажется очень простым подходом, если бы я только мог инициализировать среду выполнения c.
2 ответа
Итак, я искал источник C Runtime сегодня днем, и ответ "нет". Вы не можете предоставить свою собственную исполняемую точку входа без имени main
если вы хотите использовать C Runtime. Совсем помимо _CRT_INIT()
будучи функцией инициализации для DLL (mainCRTStartup()
является одной из функций инициализации для исполняемых файлов), mainCRTStartup()
и это как вызов main()
по имени.
- Вы можете инициализировать CRT в отдельном модуле-обертке, который имеет main; obj1
- Переименуйте основной из всех существующих модулей exe в xx_main; obj2, obj3.... objn
- Ссылка obj1 (главная) с (obj2, obj3.... objn).
Чтобы протестировать файл foo.cc, вам нужно скомпилировать и связать его с вашей программой модульного тестирования.
В чем проблема с этой схемой?
Хотя это и не задокументировано, можно инициализировать CRT в исполняемом файле таким же образом, как это можно сделать в DLL.
EXTERN_C BOOL WINAPI _CRT_INIT( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved );
// ThreadProc for CreateRemoteThread, a possible use case.
DWORD WINAPI ArbitraryAlternateEntryPoint( LPVOID )
{
_CRT_INIT( GetModuleHandle( NULL ), DLL_PROCESS_ATTACH, NULL );
// CRT functions can be used here.
_CRT_INIT( GetModuleHandle( NULL ), DLL_PROCESS_DETACH, NULL );
return 0;
}
Документация предполагает, что _CRT_INIT должен вызываться для каждого нового потока в дополнение к начальному вызову, но на практике это необязательно.