2025年编译lib文件(编译生成lib)

编译lib文件(编译生成lib)从上一篇文章中 大家已经了解到有 C 运行时库这个概念 这个不算是新东西 但是一般都隐藏在幕后 C C 语言教学的时候不讲 windows linux 编程的时候似乎也不会专门讲到 不过它一般是我们 C C 编程中默认会使用的一个重要部分 回想想 我们随手打出的 strcpy memset memcpy 等等 不就是 C 运行时库所提供出来的东西吗 既然这样 就要好好研究一下这个东西了

大家好,我是讯享网,很高兴认识大家。



       从上一篇文章中,大家已经了解到有C运行时库这个概念,这个不算是新东西,但是一般都隐藏在幕后,C/C++语言教学的时候不讲,windows/linux编程的时候似乎也不会专门讲到。不过它一般是我们C/C++编程中默认会使用的一个重要部分。回想想,我们随手打出的strcpy, memset, memcpy等等,不就是C运行时库所提供出来的东西吗?

       既然这样,就要好好研究一下这个东西了。

       前面已经说过,针对单线程/多线程,静态/动态链接,是否是debug版本,VC6的C运行时库提供了6个版本。具体可以看下面的截图。

       而其中每一个选择对应的LIB文件。这里也不全部一下子将所有的都研究一下,还是按照由浅入深的原则,从最简单的部分开始,当然,也会在牵涉到其他部分的时候,进行一定的说明。

       最简单的当然是Single-Threaded,同时也是static link的了。其对应的文件为LIBC.LIB。对应CL的编译选项为/ML。既然要研究这个LIB文件,那当然是有源码最好了,jjhou不是说过,“源码面前,了无秘密”吗。那我们在哪里找到有源码呢?

————————————

       只要你安装了VC6,它就带有CRT的源码,具体目录和你安装VC6的目录有关,在我电脑上的路径为“d:Program FilesMicrosoft Visual StudioVC98CRTSRC”,你进去之后会发现,里面有不少熟悉的名字,如“MATH.H”、“STDIO.H”、“STDLIB.H”、“STRING.H”等,由于C运行时库被C++运行时库包含,所以这里面还有C++标准库的代码,所以还能看到“IOSTREAM”、“CSTDIO”、“algorithm”等C++的std头文件。

————————————

这里就出现了一个问题,这里的文件有成百上千个,我们一个个全部看是不可能的,那如何找出关键的部分来呢?

       如果还对上一篇的分析有印象,并且带有问题的同学,应该很容易联想到,我们在link不带有defaultlibs信息的hello.obj文件时,出现了两个LINK2001错误,分别是找不到_printf和mainCRTStartup这两个symbol文件。

       编译器CL在编译C程序的时候,内部将需要编译的函数前面加上下划线()用来标识,_printf具体指的就是printf函数,_mainCRTStartup则是mainCRTStartup,是在哪里使用的呢?

       我们已经知道,printf函数和mainCRTStartup函数的实现都是在LIBC.LIB中,printf,是我们main函数中用来打印信息的,而mainCRTStartup,则是hello.exe的入口(entry point)。

       学过C语言的人都知道,有一个main函数,是一个程序的入口。不管怎样,main函数是特殊的。

       使用汇编的童鞋都知道,汇编的入口函数只是一个符号,是可以随意定义的,之后就从入口开始,PC一条条的开始执行汇编代码。对于C程序来说,main也是一个符号而已,不过这个符号与汇编的_start有些区别,_start可以用其他符号直接代替,而在windows系统下,VC开发的环境中,我们的hello.exe的main函数之前还有一个mainCRTStartup(呼,好多限制条件,好绕口……)。


讯享网

       为什么需要mainCRTStartup呢,我们还是要看一下源码实现。先搜索到mainCRTStartup所在的文件,为crt0.c,其全部代码有400多行因篇幅原因就不写出来了,想要深入了解的小伙伴可以找我。

       可以看到,里面使用了很多的宏,同时还涉及到一些例如wWinMainCRTStartup,WinMainCRTStartup,wmainCRTStartup以及我们现在需要查看的mainCRTStartup。根据不同的宏来选用不同的代码实现。

  _WIN32

  CRTDLL

  WPRFLAG

  WINMAIN

  _MT

  _M_MPPC

       因为我们这里分析的是mainCRTStartup,用的是命令行程序,非unicode版本,单线程,非PPC。所以可以将对应的一些宏去掉,最终整理得到的代码(不包含辅助函数)为:

这样,就可以分析一下得到的代码了。同时,从代码中可以看到微软的编码风格,学习到一部分。

       在mainCRTStartup()函数中,主要调用了GetVersion, _heap_init, fast_error_exit, _ioinit, GetCommandLineA, __crtGetEnvironmentStringsA,_setargv, _setenvp, _cinit, exit,以及最重要的main函数。

其中fast_error_exit位于crt0.c中,实现如下

       其他一些函数所在的文件或者说明如下,感兴趣的同学可以自行研究,这里因为篇幅原因,就不一一展开了。

       由此可见,mainCRTStartup为main函数做了一些初始化的工作,包括创建heap,初始化low IO,以及命令行参数和环境变量的获取,和初始化C runtime Data。

▓当没有做这些初始化工作,而直接使用main作为入口函数的话,是会出现很多问题的,具体在下一篇写吧。

▓由于涉及到的这部分,网络上面的参考较少,自己揣摩出来居多,有错误难免,希望大家批评指正。

我是一名从事了10年开发在退休边缘垂死挣扎的高龄程序员,最近我花了一些时间整理了一个完整的学习C语言、C++的路线,项目源码和工具 > > >C/C++编程学习开发学习视频,新鲜出炉的学生成绩管理系统,还有素材币笔记,项目源码等 ~ 对于想学习C/C++的小伙伴而言,学习的氛围和志同道合的伙伴很重要,笔者强烈推荐主页的编程爱好者的聚集地

欢迎初学和进阶中的小伙伴。希望你也能凭自己的努力,成为下一个优秀的程序员。工作需要、感兴趣、为了入行、转行需要学习C/C++的伙伴可以一起学习!”

关注我,带你遨游代码世界!

下面这些是C/C++能做的 :

服务器开发工程师、人工智能、云计算工程师、信息安全(白客)、大数据 、数据平台、嵌入式工程师、流媒体服务器、数据控解、图像处理、音频视频开发工程师、游戏服务器、分布式系统、游戏辅助等!

小讯
上一篇 2025-05-14 17:36
下一篇 2025-06-06 20:44

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/164669.html