有关C Runtime 的转载

本文探讨了CRT(C/C++运行时库)的历史和发展,解释了它与C++标准库的关系,以及CRT如何成为Microsoft编写Windows操作系统的基础。文中还讨论了CRT与Windows API之间的联系,以及CRT的不同组成部分。

首先说明,我google了半天,想找到英文的关于这个资料,但是实在找不到,只好转载国人的讨论。

 

CRT原先是指Microsoft开发的C Runtime Library,用于操作系统的开发及运行。后来在此基础上开发了C++ Runtime Library,所以现在CRT是指Microsoft开发的C/C++ Runtime Library。在VC的CRT/SRC目录下,可以看到CRT的源码,不仅有C的,也有C++的。
       CRT原先的目的就是支持操作系统的运行。因为Windows操作系统除汇编部分外,都是用C/C++编写的,所以内核及许多关键服务都在CRT上运行(它们都采用dll技术动态链接)。此外,用 VC编写的C/C++程序也用到它们(可以动态链接,也可以静态链接,前者运行时需要系统中已安装CRT的dll,后者不需要)。可以说,CRT就是 Microsoft编写Windows时使用的低层类库。然后,它又被当作C++标准库的一个实现包含在了VC系列中;我们在VC中使用的C++标准库,其实就是CRT的一个真子集(少了C++标准所不包含的代码,特别是大量的低层C代码)
       至于CRT与WINDOWS API的关系,与许多人理解的相反,WINDOWS API作为Windows的一部份,是在CRT的基础上开发的。你可以将Windows(及其API)看作一个项目,而这个项目使用的语言是汇编/C/C ++,使用的类库就是CRT。所以,离开CRT,Windows API也无法使用的。
       C++标准,是C++的通用语言规范,指导所有C ++使用者。而CRT的其中一部分可以看作是Microsoft开发的一个C++标准库实现(其实也确实如此,Microsoft在开发CRT时,参考了正在标准化过程中的C++语言规范)。它与C++标准有一定的差距,部分原因是,在C++没有完成标准化之前,CRT已经开发并投入使用了。为了向下兼容以前的Windows代码,早期的CRT与C++标准总有一定的差距。但是CRT确实在不断的改进中。VC6带的CRT与C++标准还有比较大的差距,而 VC8的几乎完全符合C++标准了。
       综上,CRT(Microsoft's C/C++ Runtime Library)的一个真子集(主要是C++ Runtime Library)是一个符合(或至少是企图符合)C++标准的C++库。而Windows API(以及Windows的其他许多部分)都是在CRT的基础上开发的。
       除了以上介绍的,在使用CRT的过程中,还需要了解的是:
      1、CRT的一些组成部分也调用了Windows API。这可能就是有人认为CRT是建立的Windows API基础上的原因。但是实际上,这一部分剥离CRT没有任何的问题。只不过Microsoft将在Windows平台上可以使用的C/C++低层库都加入到CRT中。因此,CRT中很大一部分是操作系统平台无关的(原始的CRT),是开发Windows本身及其上一切的基础。它们也可以作为一个C/C+ +库在其他操作系统平台上使用。
还有一部分,则是和Windows紧密绑定的,调用Windows API来实现的,可以看作扩展的CRT。之所以将这两部分放在一起,是因为它们都是开发Windows操作系统所需要的,也因为它们也都是Windows 平台上的C/C++程序员所需要的。这种复杂关系是Microsoft的人为因素造成的,不能因此认为CRT是建立在Windows或Windows API基础上的。
       2、CRT的大部分内容是跨硬件平台的,但是也有一些部分,是直接用汇编写成、基于硬件平台、并根据特定硬件平台做的优化(而不是将生成机器码的责任完全交给编译器)。如早期对Indel的x32做了优化,现在由加入对AMD64的优化,这部分则是不跨硬件平台的。
       关于ATL
       ATL是建立在CRT上的,如果你看了ATL的源码就知道了。至于不用链接,是因为ATL库静态链接了CRT,所以它可以在CRT之外运行。类似这样的误解在于混淆了作为低层基本库的CRT和作为产品而附带在VC中的CRT。虽然这两者是同样的代码,但是概念是不一样的。
       在编写操作系统时,你需要一个合适的低层库,以便完成一些基本的、多次重复的工作。于是,就有了CRT。在最低层的时候,根本连dll这个概念都没有的,所以CRT的源代码只能做成lib,被静态链接。然后,随着Windows越做越复杂,Microsoft提出了API的概念,它提供Windows开发者一组接口,可以直接操作Windows,这就是Windows API了。当然,Windows API也是在CRT之上编写的。
   接着, Microsoft想给予C/C++程序员以足够的支持,除了原始CRT之外,还要增加在Windows平台上编程所特有的东西,如thread等等。这些东西都是和平台相关的,只能建立在Windows API上。而这些新增内容,也被放进了CRT中。此时,CRT不仅仅包含最低层平台无关的代码,还包括平台相关的部分。如你调用CRT的 _beginthread,其实内部调用了Windows API的CreateThread。加入这些东西后,CRT仍然被用作编写操作系统;但是显然,那些调用了Windows API的部分已经失去移值性了。
       然后,CRT被封装成产品,随编译器一起发布。此时CRT产品的LIB和DLL都是Windows格式的,你不能在Windows以外的平台上使用EXE或DLL吧,这就是CRT和CRT产品的区别。Windows API的产品,或是Windows的其他许多组成部分也是一些LIB/DLL文件,这些都是表面的东西,是与Windows绑定在一起的。但是,如果你认为是先有Windows或Windows API,才有CRT的,那你就本末倒置了。除非你对CRT的定义就是那些LIB/DLL产品,而不包括用来产生它们的代码。
       就象C++编译器用来编译用C++写的编译器自身一样,Windows(及其上的编译器)用来作为平台开发和编译CRT,并也用CRT来写Windows自身(当然第一个CRT和第一个用来编译Windows的编译器不是在Windows上开发的)。就象“我”也可以先写一个类库,然后在它基础上写一个操作系统,在这个操作系统上进一步扩充这个类库,然后将它配合编译器发布出去,发展一些我的操作系统的支持者,顺便再赚点收入。或者以另一种模式发布另一个库(只是我在原来那个库上开发的一个产品,由于我独立地发布这个新库,许多人会不知道这个新库与旧库的关系。这很好,因为编程本身就是尽量隐藏细节,尽量做到对使用者透明的),吸引不同风格的开发者。这样我的付出得到了最大的回报——由于我没有发布操作系统的源代码,所以许多用户认为我不仅做了系统,还做了编译器,还开发了一个类库。做了那么多事,回报是应该的。其实他们不知道,类库是编写操作系统所必须的,编译器也是必须的,这些必须的东西却可以在操作系统之外获得更多的回报,真是太完美了!这是什么?这就是商业精神!当然这些误解对我是有好处的,我就不必到处宣扬真相了。反正我把类库的源码都发布了,也没有骗过人吧。我不过是在那个原始类库中加进了一些与我的操作系统相关的东西,以方便在我的系统上编写程序的人们,这是我的好心吧;至于有人可能产生进一步的误解,就不是我需要考虑的了……
       所以还是看看CRT的源码吧——看看那些针对硬件平台的汇编;看看VC的标准C++库和CRT关系;再看看其他操作系统的源代码,想想CRT中的哪些部分可以支持用来写操作系统,而如果我自己写系统,又需要哪些东西;甚至你可以看看DOS的源代码,想想和CRT的相似性,以及历史渊源。可惜不能看到Windows的源代码,否则一切就清楚了。
       最后再说一句,C++当然不是Microsoft的专利。但是Microsoft选择了C++,并取得了成功,这是肯定的了:象CRT,象VC,象Windows,象Office,象 SQLServer......这一方面说明了C++的优势,一方面也是Microsoft自身的因素在起作用。然后,它当然要紧抓C++的大旗,大力宣扬它自己的C++,并排斥其他的C++。这就是帝国的“风范”了。所以对Microsoft,总是即恨且爱,总希望哪天它会良心发现——当然这只是幻想罢了。不过,肯定该肯定的,否定该否定的,总是应该的。但就产品而言,Microsoft不是最好的,但大多都是最成功的,在看到它的不足的同时,也要看到它的优点。存在的即使不是合理的,也一定有它的合理性。所以,不能简单用一两句话评价Microsoft及它的成功。惟有一点是可以肯定的,它决定选择C ++,真是太英明了!

-------------------------------------------

C Runtime Library

对于上面的这个太头困惑了很久,现在转贴一张

抄来的  共同学习哈 
*************************************** 
1)运行时库就是 C run-time library,是 C 而非 C++ 语言世界的概念:取这个名字就是因为你的 C 程序运行时需要这些库中的函数. 
2)C 语言是所谓的“小内核”语言,就其语言本身来说很小(不多的关键字,程序流程控制,数据类型等);所以,C 语言内核开发出来之后, Dennis Ritchie 和 Brian Kernighan 就用 C 本身重写了 90% 以上的 UNIX 系统函数,并且把其中最常用的部分独立出来,形成头文件和对应的 LIBRARY,C run-time library 就是这样形成的。 
3)随后,随着 C 语言的流行,各个 C 编译器的生产商/个体/团体都遵循老的传统,在不同平台上都有相对应的  Standard Library,但大部分实现都是与各个平台有关的。由于各个 C 编译器对 C 的支持和理解有很多分歧和微妙的差别,所以就有了  ANSI C;ANSI C (主观意图上)详细的规定了 C 语言各个要素的具体含义和编译器实现要求,引进了新的函数声明方式,同时订立了  Standard Library 的标准形式。所以C运行时库由编译器生产商提供。至于由其他厂商/个人/团体提供的头文件和库函数,应当称为第三方  C 运行库(Third party C run-time libraries)。 
4)C run-time library里面含有初始化代码,还有错误处理代码(例如divide by zero处理)。你写的程序可以没有 math库,程序照样运行,只是不能处理复杂的数学运算,不过如果没有了C run-time库,main()就不会被调用,exit()也不能被响应。因为C run-time library包含了C程序运行的最基本和最常用的函数。 
5)到了 C++ 世界里,有另外一个概念:Standard C++ Library,它包括了上面所说的 C run- time library 和 STL。包含 C run-time library 的原因很明显,C++ 是 C 的超集,没有理由再重新来一个 C ++ run-time library. VC针对C++ 加入的Standard C++ Library主要包括:LIBCP.LIB,  LIBCPMT.LIB和 MSVCPRT.LIB 
6)Windows环境下,VC提供的 C run-time library又分为动态运行时库和静态运行时库。 
动态运行时库主要是DLL库文件msvcrt.dll(or MSVCRTD.DLL for debug build),对应的Import library文件是MSVCRT.LIB(MSVCRTD.LIB for debug build) 
静态运行时库(release版)对应的主要文件是: 
LIBC.LIB (Single thread static library, retail version) 
LIBCMT.LIB (Multithread static library, retail version) 
msvcrt.dll提供几千个C函数,即使是像printf这么低级的函数都在msvcrt.dll里。其实你的程序运行时,很大一部分时间时在这些运行库里运行。在你的程序(release版)被编译时,VC会根据你的编译选项(单线程、多线程或DLL)自动将相应的运行时库文件  (libc.lib,libcmt.lib或Import library msvcrt.lib)链接进来。 
编译时到底哪个C run-time library联入你的程序取决于编译选项: 
/MD, /ML, /MT, /LD   (Use Run-Time Library) 
你可以VC中通过以下方法设置选择哪个C run-time library联入你的程序: 
To find these options in the development environment, click Settings on the Project menu. Then click the C/C++ tab, and click Code Generation in the Category box. See the Use Run-Time Library drop-down box. 
从程序可移植性考虑,如果两函数都可完成一种功能,选运行时库函数好,因为各个 C 编译器的生产商对标准C Run-time library提供了统一的支持. 

<think>好的,我需要帮助用户解决关于动态链接库slm_runtime_windows_0810BF_x64.dll配置的问题。首先,用户提到报错是因为缺少或错误放置了这个DLL文件。我的思路应该是先确认常见解决方法,然后结合用户提供的引用内容,看看是否有相关的配置建议。 首先,常规的处理DLL缺失问题的方法包括重新安装程序、下载DLL文件并放到正确位置、注册DLL、运行系统检查工具等。用户提供的引用中有Dockerfile的配置,虽然看起来Windows DLL问题不直接相关,但可能涉及到应用程序部署时的路径问题。比如在Docker中,WORKDIR设置工作目录,COPY命令复制文件,可能需要确保DLL文件被正确复制到容器内的对应目录。 不过用户的问题可能是在Windows环境下,而不是Docker。但引用中的Dockerfile示例可能提示用户的应用是在容器中运行,或者有相关的部署配置需要注意。这时候需要确认DLL是否应该放在应用程序的工作目录,或者系统目录中。例如,Dockerfile中的WORKDIR是/app,COPY . . 会将当前目录所有文件复制到容器的/app下,所以可能需要将DLL文件放在宿主机的项目目录中,确保被复制到容器内的正确位置。 另外,用户可能没有将DLL放在系统路径或应用程序所在目录,导致运行时找不到。需要建议用户检查DLL的位置是否正确,是否与应用程序的可执行文件在同一目录,或者是否在系统的PATH环境变量包含的路径中。 还可能涉及到依赖问题,比如该DLL是否有其他依赖项,或者是否需要特定版本的运行时库。这时候建议用户使用Dependency Walker工具检查依赖关系。 另外,用户提供的引用[2]是一个转载链接,可能包含一些配置技巧,但链接已失效,无法查看具体内容。可能需要忽略这部分,或提示用户确保参考最新的可靠资源。 总结步骤应该是:确认DLL位置、下载可靠版本、注册DLL、检查依赖、系统修复工具、环境配置。同时结合Dockerfile的配置,确保在容器部署时文件被正确复制。 需要注意用户可能混淆了不同环境的问题,比如在Windows本地运行Docker容器中的配置差异,需分别考虑。如果问题出现在Docker中,需要确保DLL被包含在构建上下文中,并通过COPY指令复制到容器内适当位置,比如/app目录。同时,在Windows系统本身,需要按照常规的DLL配置方法处理。 最后生成相关问题,应该围绕DLL配置、Docker部署、依赖检查等方面。</think>### 动态链接库配置方法 对于缺少或错误放置$slm\_runtime\_windows\_0810BF\_x64.dll$导致的报错问题,可按照以下步骤排查解决: 1. **确认DLL文件位置** - 将$slm\_runtime\_windows\_0810BF\_x64.dll$放置在应用程序的**同级目录**或系统目录: - Windows系统目录:`C:\Windows\System32`(64位系统)或`C:\Windows\SysWOW64`(32位系统) - 应用程序根目录(例如Dockerfile中定义的`WORKDIR /app`)[^1] 2. **通过Docker部署时的配置** ```dockerfile FROM microsoft/dotnet:2.2-aspnetcore-runtime WORKDIR /app COPY . . # 确保.dll文件在构建上下文中 EXPOSE 7000 ENTRYPOINT ["dotnet", "NetCoreSqlSugar.dll"] ``` - 需确认.dll文件与`NetCoreSqlSugar.dll`位于同一目录,并通过`COPY`指令正确复制到容器内 3. **依赖项检查** - 使用工具`Dependency Walker`检查.dll文件的依赖关系 - 确保所有依赖的运行时库(如Visual C++ Redistributable)已安装 4. **注册DLL文件(谨慎操作)** ```cmd regsvr32 slm_runtime_windows_0810BF_x64.dll ``` *注意:仅适用于COM组件类型的DLL,非标准DLL注册可能导致系统不稳定* 5. **系统级修复** - 运行系统文件检查工具: ```cmd sfc /scannow ``` - 使用Windows更新安装最新系统补丁 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值