微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将入口点过程从“ WinMain”更改为“ main”或任何自定义函数?

如何解决如何将入口点过程从“ WinMain”更改为“ main”或任何自定义函数?

我已经阅读了很多有关如何更改WinMain入口点过程的信息,有人说您可以从链接器更改入口点,而另一些人则可以将WinMain放入DLL({ {1}})等等。

老实说,我很困惑。我相信有一种或多种将入口点过程更改为自定义过程的方法,因为有一些示例,例如MFC没有直接的dllMain函数,而Qt框架也有一个自定义入口点过程,与控制台应用程序WinMain函数main类似,因此,有一些我所期望的方法

我想以某种方式替换/更改Windows上的GUI应用程序的入口点过程,从传统的过程int main(int argc,char *argv[])更改为WinMain,例如Qt或什至任何其他自定义函数,但它必须与(MS,GCC,Clang)编译器。

int main(int argc,char *argv[])

我该怎么做?

解决方法

exe

入口点可以通过任何带有签名的功能

ULONG CALLBACK ep(void* )

可能并使用ULONG CALLBACK ep()-尽管在 x86 上返回后将返回错误的堆栈指针( esp ),但这不会导致错误,因为Windows只会调用 ExitThread 返回条目后,如果它完全返回控制权-通常调用 ExitProcess 而不是返回。

该入口点的名称当然根本不起作用-它可以是任何有效的 c / c ++ 名称。找到/调用的入口点不是按名称而是由AddressOfEntryPoint偏移IMAGE_OPTIONAL_HEADER

但是当我们构建 PE 时-我们需要告诉该函数链接程序名称,因为它可以设置 AddressOfEntryPoint ,但是此信息(函数名称)仅在构建期间使用进程(不在运行时使用)

当然,不同的链接器具有不同的选项, link.exe 具有选项/ENTRY。此选项是可选的,默认情况下,起始地址是C运行时库中的函数名称。

如果明确声明了/ENTRY:MyEntry-按原样使用- MyEntry 将用作入口点。如果未设置/ENTRY选项-使用默认值:

如果设置了/SUBSYSTEM:CONSOLE-使用了 mainCRTStartup 或未找到 wmainCRTStartup

如果设置了/SUBSYSTEM:WINDOWS-使用了 WinMainCRTStartup ,或者未找到 wWinMainCRTStartup

,但是在大多数情况下, c / c ++ 开发人员使用 CRT 库。不管是与 CRT 一起使用静态链接还是动态链接-某些lib代码始终与您的 exe 静态链接,并且此代码包含用作入口点的函数。对于ms Windows crt-这是 mainCRTStartup wmainCRTStartup (对于控制台应用程序), WinMainCRTStartup wWinMainCRTStartup (针对gui应用)。

在所有这四个函数中-按名称称为硬编码函数

  • mainCRTStartup 呼叫 main
  • wmainCRTStartup 呼叫 wmain
  • WinMainCRTStartup 呼叫 WinMain
  • wWinMainCRTStartup 呼叫 wWinMain

当然,必须在您的代码中的某个位置或另一个lib代码中实现称为函数的功能。例如,如果您使用 MFC -它会自行实现 wWinMain 并以另一种方式调用代码(通过在您覆盖的对象上调用虚函数-{{ 1}}和InitApplication

如果再次提出疑问,如何更改自定义入口点的名称-但要做什么呢?您真的不需要更改名称。您只需要了解入口点的调用方式即可。如果您了解这一点-您几乎可以做得到。


假设我们要使用 InitInstance 作为“入口点”。我将其用引号引起来,因为我们确实希望在 CRT 代码中具有真实的切入点,并且希望 CRT 代码完全调用 main 功能。

可能吗?简单地! 设置main链接器选项。因此 /ENTRY: mainCRTStartup 将是真正的入口点,并调用 mainCRTStartup

另一个问题,我个人认为这是毫无意义的把戏,什么也不会改变,也不会给


也可能只需从main调用main

WinMain
,

它必须与(MS,GCC,Clang)编译器兼容

如何执行此操作取决于您的编译器。他们中的大多数人都有一些标志来选择要定位的“子系统”(Windows术语),甚至手动定制入口点。

换一种说法,没有标准的方法可以这样做,因为这超出了C ++标准的范围。

话虽如此,有些编译器提供了模拟其他编译器标志的方法。例如,Clang可以模仿微软的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。