C Run-Time library part 2
I was suggested when I have some further questions on my older ones, to create newer Question and refer to old one. So, this is the original question: What is the C runtime library?
OK, from your answers, I now get thet statically linked libraries are Microsoft implementation of C standard functions. Now:
If I get it right, the scheme would be as follow: I want to use printf(), so I must include <stdio.h>
which just tells compiler there is a function printf() with these parameters. Now, when I compile code, because printf() is defined in C Standard Library, and because Microsoft decided to name it C Run Time library, it gets automatically statically linked from libcmt.lib (if libcmt.lib is set in compiler) at compile time. I ask, becouse on wikipedia, in article about runtime library there is that runtime library is linked in runtime, but .lib files are linked at compile time, am I right?
Now, what confuses me. There is .dll version of C standard library. But I thought that to link .dll file, you must actually call winapi program to load that library. So, how can be these functions dynamically linked, if there is no static library to provide code to tell Windows to load desired functions from dll?
And really last question on this subject - are C Standard library functions also calls to winapi even they are not .开发者_StackOverflowdll files like more advanced WinAPI functions? I mean, in the end to access framebuffer and print something you must tell Windows to do it, since OS cannot let you directly manipulate HW. I think of it like the OS must be written to support all C standard library functions same way across similiar versions, since they are statically linked, and can differently support more complex WinAPI calls becouse new version of OS can have adjustements in the .dll file.
To address your questions in order:
Wikipedia is misleading you. The runtime library is not always linked at runtime, and is not in the case where you have chosen a statically linked runtime (libcmt.lib
).
There is a .dll
version of the runtime library (which is linked at runtime) and the compiler knows how to generate the appropriate instructions in the .exe
file to tell the loader to load the runtime library .dll
at runtime.
There are two APIs here. One is the Win32 API, which is the list of functions supported by the Windows OS itself. The other API is the C runtime API which is defined by the C programming language standard. Some C runtime library functions, such as opening and reading files, will eventually make Win32 API calls to do the actual file I/O. Other C library functions, like for example strlen()
, do not interact with the OS and are implemented using code completely inside the runtime library itself.
The linked in C Run Time is a wrapper around your "main" function; it initializes everything that is needed before your C code can be run. It does not contain (m)any "functions", those are in the C standard library (which is dynamically linked).
I think you misunderstand dynamic linking: it's done by the OS. So you tell the OS that your executable needs DLL a
, b
, c
and d
. The time you execute your executable, the OS will load the executable in a memory location, and reads in the executable what is necessary to run it. It will then grab those DLLs and paste them in the memory region of your executable, and then it tells your code that a
is loaded at x
, b
is loaded at y
, etc. so your code can call it's functions.
Sometimes, compilers include (called statical linking) a library at compile-time: they do that, such that the OS doesn't have to load it at runtime, and thus loads faster.
.lib
files are DLL files without the "D", because they can be statically linked. It's also possible to dynamically link against library files; this makes your executable smaller, but makes load time of your executable slower.
About the WinAPI: most calls to the C library are converted into (some) calls into the WinAPI; but only if they have to interact with the OS (I/O, etc.). The difference is that the C library is equal on most platforms, so it increases portability if you use the C library instead of the Windows API's directly.
Update:
You asked how to load a DLL if you completely dynamically link your executable? Well: you don't have to! The difference between the "load dll" and "call to load dll" is; the "load dll" is done by the OS when you launch the application. The OS will search your executable for a specific "import table". It's a table stating which DLLs it really needs, before it can execute (i.e. kernel32.dll
or user32.dll
on Windows). The OS will make the "call to load dll", even before your code runs.
The "call to load dll" also exists in kernel32.dll
for your code to be called: it's possible to load/unload DLLs while your code runs. This can be of a case, if you have a huge code-base and you want to free memory by unloading that one-time use library during your whole application lifetime (for instance, during startup). If you don't use the function anymore, you can unload the DLL. But it's also possible that you need some function, which you haven't loaded yet, to speed up loading. You can then load the DLL if you need the function yourself. This is quite advanced stuff, and most of the time, the OS will swap away the unused DLLs anyway ("removing" memory, literally: it moves the memory that isn't used much (like an unused DLL) to a place of mass storage, like the harddisk. If you need it, it automatically "swaps" it back!).
So: you don't have to concern much about loading/unloading DLLs on Windows. If you have a good linker, and tell it to dynamically link against libraries, it will all work out just fine.
In Visual C++ and some other compilers, the CRT is linked in for you, unless you explicitly tell it not to (sometimes useful for keeping code size down).
In the compiler options, you can choose whether to have the Debug or Release versions and whether its' statically linked or dynamically.
Static linking puts all the actual code from all the CRT functions you call directly into your EXE. This is useful for reducing how many external dependencies you require - you can just run the EXE and no worry about whether you have the right xxxx.dll installed. The disadvantage is that the CRT functions you shipped might have problems (security exploits, crashes, race conditions) and the only way your end user can fix these problems is if you produce a new EXE.
Dynamic linking puts a reference to the CRT functions you call from your EXE. When your EXE loads and your code makes a call to a referenced function, the OS dynamic loader will see that actually, that function is in MSVCRT[D][version].dll and go load that DLL, look up the address of the function and then fixup the reference in your code to point directly to the function in the DLL, so that next time, it is as fast as if you'd statically linked it. Clearly, there's an initial startup delay here (compared to static link) but the advantages are enormous: system DLL's get patched by Microsoft, so you can get updates to problems (see above), loaded DLL's are shared in memory, so if a DLL you reference is actually already used by another process, it takes less time to load it up as the other process did a lot of the work already.
Finally, yes, the CRT functions like printf() and scanf() do eventually talk to Win32 API's, but not always the ones that you think. Use the 'DEPENDS' tool in Visual Studio/Windows SDK or SysInternals 'ProcExp' to see which DLL's are pulled in by any particular process and what functions they are using.
精彩评论