目标环境: WindowXP SP3 + VS2008.NET
开发语言: C/C++
目标生成: Console Application and Window Application.
有的时候,需要会遇到这样的一个情况,“想要在main或者WinMain函数执行前初始化我们的系统框架,和在之后释放我们的系统框架”, 如果这样,我们该怎么做呢?笔者今天放假,来公司继续解决昨天剩余的问题,然后调试exit函数的时候,会发现它会调用
static void __cdecl doexit (int code,int quick,int retcaller)这样的一个内部函数,那么继续单步调试,那么你就会发现
这段代码,OK,我们移上去(function_to_call)看看,你会发现是那些全局类变量的析构调用,那么我们继续往下面走,_initterm(__xp_a, __xp_z); 这个函数, 我第一次看到这个函数的时候,莫名其妙想在里面做文章了。。。OK,我们去看看这个函数内部到底是干什么的
很容易就可以看到,他就是一个循环遍历,执行每个元素,而仔细看看,那每个元素不就是一个函数指针吗? OK,我们想实现前面所说的功能,该怎么做呢?怎么能够自动往里面添加我们的函数指针呢? 如果能够自由添加我们的函数指针的话,就可以在main和WinMain之前,之后分别调用我们自己的 “初始化”“退出”函数了。那么我们继续在这个源文件中“crt0dat.c”中看看其他代码,或许你会幸运的发现如下代码:
MS也给我们写了一点注释, __xi_a[] 到 __xi_z[] 是用于 C语言初始化用的, __xc_a[] 到 __xc_z[] 适用于C++初始化用的,而
__xp_a[] 到 __xp_z[] 适用于C基本库预结束用的, __xt_a[] 到 __xt_z[] 适用于C基本库结束用的。通过这里,我们可以看到那个字符串中的英文字母".CRT$XIA" - ".CRT$XIZ", 我们可以分析出一些简单的规律,
I --> C initialize;
C --> C++ Initialize
P --> C PreUninitialize
T --> CUninitialize
这时候,我们需要查找 _CRTALLOC 宏定义, 通过查找它所引用的头文件,可以看到其中的sect_attribs.h:
OK,得到上述的那些信息,我们可以开始尝试了,输入以下代码:
那么,你可以Ctrl+F5测试一下, 你可以看到 init A() main() ~A() uninit 这样的顺序,呵呵,总之目标实现啦,其实原理也很简单的,我就不讲啦, 杭州天气太热了。。。
参考文章:
1. http://www.codeguru.com/cpp/misc/misc/threadsprocesses/article.php/c6945__1/Running-Code-Before-and-After-Main.htm
2. http://book.51cto.com/art/200904/121077.htm
分享到:
相关推荐
在C/C++编程中,入口函数是程序执行的起点,它是程序执行的首个被执行的代码块。最常见的入口函数是`main`函数,它的标准形式如下: ```cpp int main(int argc, char* argv[]) { // 程序代码 return 0; } ``` 在...
在`qt.txt`文件中,可能包含了更详细的QT框架使用、`WinMain`和`main`函数的差异,以及如何在QT中创建和管理窗口的示例代码和解释。深入学习这些内容将有助于理解QT在Windows环境下的工作原理,以及如何高效地利用QT...
在Windows编程领域,`WinMain`函数是应用程序的入口点,尤其在开发基于Windows操作系统的桌面应用程序时。它类似于C/C++中的`main`函数,但具有特定于Windows的上下文,提供了与操作系统更深入的集成。让我们深入...
在压缩包中的"Code"文件,很可能是包含了一个完整的示例程序,包含了`WinMain`函数的实现和其他相关代码。这个程序可以直接编译运行,帮助初学者更好地理解和实践`WinMain`的用法。 学习和理解`WinMain`函数对于...
在Windows编程领域,"Windows框架"是构建图形用户界面(GUI)应用程序的基础,而`WinMain`函数则是这个框架...通过研究这些示例,你可以更好地掌握如何在实际项目中运用`WinMain`函数,从而构建自己的Windows应用程序。
- 如果你在VC中打开了一个`.c`或`.cpp`文件,并直接对该文件进行了编译,且该文件中使用了`WinMain`而不是`main`作为入口函数。 - 此时VC默认会将其视为控制台程序进行编译,因此会期待一个名为`main`的函数作为...
这段代码的主要职责是在调用用户定义的`main`或`WinMain`之前完成一系列初始化工作,比如设置环境变量等。这部分代码会设置好调用`main`或`WinMain`所需的参数,并最终调用它们。 #### 参数传递 如代码片段所示,...
在Windows操作系统中,WinMain函数是应用程序的入口点,它在C++编程中扮演着重要的角色,尤其是在开发基于Windows的应用程序时。这个函数是Windows API(应用程序接口)的一部分,替代了传统的C运行库中的main函数。...
在Windows API中,`WinMain`替代了`main`,并接收四个参数:`hInstance`(当前进程实例句柄)、`hPrevInstance`(已弃用,通常为NULL)、`lpCmdLine`(命令行参数)和`nShowCmd`(显示窗口的方式)。这个函数是程序...
- `WindowsProject1.zip`可能包含了一个Windows应用程序的源代码或者编译结果,其中可能包含了对DLL的引用。 - `windowsmaindll.zip`很可能包含了"WindowsMain.dll"文件本身,供其他程序使用。 - `windowsmainexe...
2. **代码转换**:将原有的EXE代码重构为DLL代码,这意味着需要将主入口点(main或WinMain)替换为DllMain,这是DLL的初始化函数。DllMain会在DLL被加载时调用,是实现DLL自启动的关键。 3. **嵌入EXE到DLL**:为了...
进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成,进程在运行过程中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放或关闭。 线程是进程...
例如,以下代码中的整型变量`a`会在`main()`函数执行前就被初始化为88。 ```c #include int a = 88; int main() { std::cout ; } ``` 如果在`main()`函数前设置断点,会发现在进入`main()`函数之前,全局...
多线程概述 ...系统创建好进程后,实际上就启动执行了该进程的主执行线程,主执行线程以函数地址形式,比如说main或WinMain函数,将程序的启动点提供给Windows系统。主执行线程终止了,进程也就随之终止。
这段代码实现了加载JVM动态库、创建Java虚拟机、查找并执行Java主类中的`main`方法等功能。 ##### 3.2 打包Java代码为JAR文件 接下来,需要将Java代码打包为JAR文件。这一步可以通过Eclipse IDE或者其他构建工具...
- **无用户界面**:大多数服务并不需要图形用户界面(GUI),它们通常是以控制台程序的形式编写的,使用`main()`作为入口点而不是用于GUI程序的`WinMain()`。 **1.2 服务的安全性** 为了编写服务,开发者需要了解...
本文将详细介绍如何将Java代码打包成exe格式的可执行文件,使得Java应用程序可以在不安装JRE(Java运行环境)的情况下运行。这一过程对于那些希望将Java程序发布给非技术用户的开发者尤为重要,因为它简化了最终用户...
2. **定义WinMain函数**:在Windows程序中,主入口点是`WinMain`函数,而不是常见的`main`函数。`WinMain`函数接收四个参数:程序实例句柄、命令行参数、前一个实例句柄以及窗口类的实例句柄。 3. **注册窗口类**:...
DLLMain函数是每个DLL的入口点,类似于应用程序的WinMain或main函数。当DLL被加载到进程空间时,DLLMain函数会被自动调用。这个函数通常用于初始化和清理资源,设置全局变量,或者进行其他必要的设置。 DLLMain函数...