Как явно вызывать функции запуска CRT

Есть ли способ, которым я могу явно в своем коде вызвать функции, которые обычно вызываются в функциях mainCRTStartup? Меня особенно интересуют функции initterm и initterm_e. Даже при том, что моя программа связана с crt (должно быть, верно?), Я не мог просто вызвать initterm - я попытался объявить и просто вызвать, и я получил неопределенную ссылку.

Есть ли способ сделать это?

1 ответ

Решение

_initterm и _initterm_e (примечание в msdn _initterm_e неправильно заявлено - действительно оно используется _PIFV тип) экспортируется различными библиотеками CRT. и это объявлено в файлах lib тоже. и реализация этой функции очень проста:

typedef void (__cdecl *_PVFV)();

void _initterm(const _PVFV *ppfn, const _PVFV *end)
{
    do 
    {
        if (_PVFV pfn = *++ppfn)
        {
            pfn();
        }
    } while (ppfn < end);
}

typedef int  (__cdecl *_PIFV)();

int _initterm_e(const _PIFV *ppfn, const _PIFV *end)
{
    do 
    {
        if (_PIFV pfn = *++ppfn)
        {
            if (int err = pfn()) return err;
        }
    } while (ppfn < end);

    return 0;
}

так что вы можете импортировать его или не использовать собственную реализацию. Здесь более быстрый вопрос - что использовать в качестве входных параметров?

скажем с ++ (CL компилятор, как минимум) использовать ( ".CRT$XCA", ".CRT$XCZ" ) разделы для места с ++ глобальной инициализации. поэтому мы можем сделать следующее:

extern "C"
{
#pragma const_seg(".CRT$XCA")
  const _PVFV __xc_a = 0;
#pragma const_seg(".CRT$XCZ")
  const _PVFV __xc_z = 0;

#pragma const_seg(".CRT$XIA")
  const _PVFV __xi_a = 0;
#pragma const_seg(".CRT$XIZ")
  const _PVFV __xi_z = 0;
}

    /*
     * do initializations
     */
    initret = _initterm_e( &__xi_a, &__xi_z );
    if ( initret != 0 )
        return initret;

    /*
     * do C++ initializations
     */
    _initterm( &__xc_a, &__xc_z );

но тут нужно очень хорошо понять - что и для чего мы делаем

Другие вопросы по тегам