【问题标题】:How do I obtain a function pointer to the main() method in C++?如何在 C++ 中获取指向 main() 方法的函数指针?
【发布时间】:2012-03-17 01:49:29
【问题描述】:

我正在研究 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() 上准确地写了 void,而不是 int?

【问题讨论】:

  • 在 C++ 中,main 必须返回 int。而且由于 C++ 程序不能调用 main(这是被禁止的),我看不出指向它的指针有多大用处(如果允许的话)
  • @R.MartinhoFernandes:有点错误,它必须有返回类型int,它实际上不必返回什么。
  • @smerlin:它总是返回一些东西。如果控制在没有遇到return 语句的情况下结束,则标准规定它将返回0
  • @user1131997:正确,但void main() is a Microsoft specific extension to the language according to the MSDN docs。它可能不适用于其他 C++ 编译器。 用标准 C++ 编写并避免编译器特定的扩展,除非它们是绝对必要的。
  • @user1131997:这并不能改变你根本不应该这样做的事实。在 C++ 中调用 main 是非法的。即使它恰好起作用,你不应该这样做!

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


【解决方案1】:

下面是获取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,例如微软自己的文档中的非标准示例将被编译。无论如何,这就是我的理论 #1,因为你问。但这当然是纯粹的猜测,甚至那些编写代码的人也可能不清楚原因(理论 #2)。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-01
      • 2014-03-22
      相关资源
      最近更新 更多