如何在C ++中获取指向main()方法的函数指针?

时间:2012-03-17 01:49:29

标签: c++ visual-c++ pointers function-pointers

我正在研究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 ...的信息,但是我在main()上写了空,而不是int?

2 个答案:

答案 0 :(得分:4)

以下是获取指向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是一个非常特殊的功能。

这些规则(通常)不适用于其他功能。

另请注意,在不诊断void结果类型时,Visual C ++是错误的。

最后,请注意,编写非标准void比标准int更多地输入一个字符,即,它只是一个非常非常愚蠢的事情。 ; - )

PS:Visual C ++可能可能关于int main的事情,因为它(可能)在内部将void main翻译为int main,可能它会这样做事物与非智能链接器链接,同时积极支持void main,例如微软自己的文档中的非标准示例将进行编译。无论如何,这是我的理论#1,因为你问。但它当然是纯粹的猜测,也许甚至那些编码起来的人也不清楚为什么(理论#2)。

答案 1 :(得分:2)

好吧,如果你真的想要更改可执行文件的入口点,请按照此处的steps找到可选标题,偏移16个字节并更改4个字节。您可以找到PE规范here。为了在运行时更改可执行文件本身,您需要一些程序集技巧,或者发出另一个可执行文件,运行批处理并终止正在运行的进程。