Как получить указатель на функцию main () в C ++? - PullRequest
1 голос
/ 17 марта 2012

Я работаю над компилятором MS C ++ и выполнил следующую программу:

#include <stdio.h>

void main(void)
{
    void(*ptr)(void) = &main;
}

Я хотел сделать указатель на метод / функцию main (), но получил следующую ошибку:

error C2440: 'initializing' : cannot convert from 'int (__cdecl *)(void)' to 'void (__cdecl *)(void)'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast

Интересно:

  • как мне получить указатель на функцию / метод main ()
  • , почему по умолчанию в выходных данных есть информация о int __decl..., но я точно написал void на main (), а не int?

Ответы [ 2 ]

4 голосов
/ 17 марта 2012

Вот как получить указатель на функцию main:

#define DECLARE_UNUSED( name ) (void) name;  struct name

int main()
{
    int(*ptr)() = &main;
    DECLARE_UNUSED( ptr );    // Prevents using `ptr`.
    // Don't use `ptr` here. In particular, don't call.
}

Обратите внимание, что

  • main должен иметь тип результата int.

  • вызов main (например, через этот указатель) приводит к неопределенному поведению.

  • Нет необходимости возвращать что-либо из main;возвращаемое значение по умолчанию равно 0.

Как видите, main - это особая функция.

Эти правила (в общем случае) не применяются к другим функциям.

Также обратите внимание, что Visual C ++ неверен в том, что не диагностирует void тип результата.

Наконец, обратите внимание, что написание нестандартного void на один символ больше, чем тип int то есть это очень, очень глупая вещь.; -)

PS: Visual C ++ , вероятно, бормотает о int main, потому что он (вероятно) переводит void main в int main внутри, и, вероятно, это делает это, чтобы сделать вещисвязываться с неинтеллектуальным компоновщиком, активно поддерживая void main, так что, например, будут собраны собственные нестандартные примеры Microsoft в их документации.В любом случае, это моя теория # 1, так как вы спрашиваете.Но это, конечно, чисто догадки, и даже те, кто их кодировал, не имеют четкого представления о том, почему (теория № 2).

2 голосов
/ 20 марта 2012

Что ж, если вы действительно хотите изменить точку входа исполняемого файла, найдите дополнительный заголовок, выполнив шаги , сместите 16 байтов и измените 4 байта.Вы можете найти спецификацию PE здесь .Чтобы изменить сам исполняемый файл во время работы, вам понадобится какой-то трюк с сборкой, или создайте другой исполняемый файл, запустите пакет и завершите запущенный процесс.

...