|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
1. The PurposeThe purpose of this article is to clear the essential points about Windows API, C Runtime Library (CRT) and Standard C++ Library (STL). It is not uncommon that even experienced developers have confusion and hold onto misconceptions about the relationship between these parts. If you ever wondered what is implemented on top of what and never had a time to figure it out, then keep reading. 2. BasicsThe following diagram represents the relationship between WinAPI, CRT and STL.
Adjacent blocks can communicate with each other. What does it mean? Let's go from the bottom to the top. 2.2. HardwareEach hardware part exposes its own set of commands that enables operating system to control and communicate with it. An amount and complexity of commands varies from part to part. Often different vendors of the same part may provide additional commands beyond requirements of a common standard. Communication with countless hardware devices with endless variety of commands would be enormous toil for software writers if they had to access it directly. Here operating system comes to the rescue. 2.3 Operating SystemThe purpose of the OS is to encapsulate all intricacies of underlying hardware and provide unified access interface to computer's parts. No application can access hardware directly. Only OS can access hardware. The part of the OS that accesses hardware is said to run in kernel mode. Older OS'es like MS-DOS, for example, allowed programs to access hardware resources directly. Though it enabled software writers to make certain performance gains, in the long run this technique often made the software very brittle and incompatible with newer hardware parts. 2.4 Application Programming InterfaceOS exposes underlying machine resources by means of Application Programming Interface (API). API is a uniform set of functions that enables software developers to abstract from hardware peculiarities and focus on their own goals. Application cannot bypass an OS and access hardware resources directly. It is commonly said that applications run in user mode. MS Windows provides API as a set of C functions. C language is chosen as the lowest common denominator for software development under Windows platform. 2.4.1 Platform Software Development KitMS distributes for free Platform Software Development Kit (Platform SDK or PSDK), which enables software developers to write Windows programs. PSDK contains:
For example, to open or create a file one calls Names of Windows API functions follow Camel case naming convention and usually are easily distinguished by this. Names of macros and constants are conventionally in uppercase. Each function always has "Requirements" section on its documentation page where necessary headers, import libraries and supported OS versions are specified. A Windows application can call any API function, provided application follows function's signature and links with appropriate import library (or gets function's address directly from implementing DLL with 2.5 C Runtime LibraryOn top of OS API functions software vendors implement C Runtime Library (CRT). CRT is a standardized set of header files and C functions, which implement common tasks, such as string operations, some math functions, basic input/output etc. Usually the same vendor that makes C compiler also provides CRT implementation. International Organization for Standardization [^] is responsible for C language standard and its runtime library. 2.5.1 Standards and ExtensionsTheoretically, by using only standard C functions developer can ensure that the same code may be used to build and run a program under any platform where decent C compiler and CRT implementation exists. However, in practice software vendors include many useful extensions to standard library functions, which make developers' life easier but at a price of portability. Names of CRT functions are in lower case. Names of macros and constants are in uppercase. Names of extensions begin from underscore character, for example
2.6 Unicode Awareness2.6.1 Platform SDK Is Already Unicode AwareActually, the above mentioned Win32 API names are not real names. These names are mere macros that defined in PSDK header files. So, when PSDK documentation mentions a function, for example There are three families of Windows OS: MS-DOS/9x-based, Windows CE and Windows NT. 2.6.2 PSDK Solution: TCHAR'sIn order to avoid multiple PSDK's for different Windows families Microsoft implemented generic text characters or // Generic code
//
LPCTSTR psz = TEXT("Hello World!");
TCHAR szDir[MAX_PATH] = { 0 };
GetCurrentDirectory(MAX_PATH, szDir);
// What actually happens if UNICODE symbol is NOT defined for a build
//
const char* psz = "Hello World!";
char szDir[MAX_PATH] = { 0 };
GetCurrentDirectoryA(MAX_PATH, szDir);
// GetCurrentDirectoryA is a wrapper. It does the following:
// 1. Allocates temporary wchar_t buffer of given size.
// 2. Calls real worker: GetCurrentDirectoryW.
// 3. Calls WideCharToMultiByte in order to convert wchar_t string into
// char string according to the active code page for a calling thread.
// If some character cannot be converted, then it will be replaced with the '?' symbol.
// What actually happens if UNICODE symbol is defined for a build
//
const wchar_t* psz = L"Hello World!";
wchar_t szDir[MAX_PATH] = { 0 };
GetCurrentDirectoryW(MAX_PATH, szDir); // direct call to real worker; no wrappers in the middle
Using The easy way to remember PSDK string declarations is to say them loud: Here are two screenshots of the same progam. First screenshot is taken when the program is built as ANSI. Second screenshot demonstrates Unicode build of the program.
2.6.3 CRT Solution: _TCHAR'sFollowing Platform SDK logic Microsoft introduced generic text mapping into its C runtime library. CRT uses additional header file to define generic character macros: "tchar.h". In order to be compliant with requirements of the C language standard all non-standard names start from the underscore symbol. Also, CRT uses shorter
CRT uses
// Generic code; names are not standard, hence the leading underscore.
//
_TCHAR message[128] = _T("The time is: ");
_TCHAR* now = _tasctime(&tm);
_tcscat(message, now);
_putts(message);
// What happens if no symbol is defined at all (SBCS).
//
char message[128] = "The time is: ";
char* now = asctime(&tm);
strcat(message, now);
puts(message);
// What happens if _MBCS symbol is defined (Multi-byte Character Set);
// non-standard names are with the leading underscore.
//
char message[128] = "The time is: ";
char* now = asctime(&tm);
_mbscat(message, now);
puts(message);
// What happens if _UNICODE symbol is defined (Unicode Character Set);
// non-standard names are with the leading underscore.
//
wchar_t message[128] = L"The time is: ";
char* now = _wasctime(&tm);
wcscat(message, now);
_putws(message);
2.7 C++ Standard LibraryC++ programming language defines its own standard library. C++ Standard Library specifies a set of classes and functions that facilitate common programming tasks. Often C++ Standard Library is referred as STL. This abbreviation belongs to pre-standard times and stands for Standard Template Library. Since latest revision of C++ standard STL became a subset of C++ Standard Library. However, the term STL is still ubiquitous and used as a synonym for C++ Standard Library. International Organization for Standardization [^] is responsible for C++ language standard and its library. 2.7.1 Contents of C++ Standard LibraryC++ Standard Library may be divided into following major parts:
2.8 Cross-platform DevelopmentSometimes there is requirement that software program will run on several computer platforms. Developer may choose to develop as many separate code bases of software as there are target platforms. However, this approach is tedious and error prone. It is also wasteful and ineffective considering development resources since the same functionality must be implemented and maintained over and over again. The common approach is to develop single code base for all platforms and restrict the usage of platform-dependent API functions and vendor-specific standard libraries extensions. It makes development harder, however, in the long run all platforms benefit from new features and bug fixes. 3. Code ReuseThere are two ways to incorporate CRT and/or C++ Library code into a program: 1) static linking and 2) dynamic linking. In the following discussion I will use solely CRT term to save typing, however these concepts are relevant both to CRT and C++ Standard Library. 3.1 Linking StaticallyWhen CRT/C++ Library linked statically, then all its code is embedded into resulting executable image. This technique has both advantages and disadvantages. Advantages:
Disadvantages:
3.1.1 CRT As A Black BoxThe problem is that internal CRT objects cannot be shared with other CRT instances. The memory allocated in one instance of CRT must be freed in the same instance, the file opened on one instance of CRT must be operated and closed by functions from the same instance, etc. It happens because CRT tracks acquired resources internally. Any attempt to free memory chunk or read from file via That's why linking CRT statically obligates a developer of a module to provide additional functions to release allocated resources and a user of a module to remember to call these functions in order to prevent resource leaks. No STL containers or C++ objects that use allocations internally can be shared across modules that link to CRT statically. Following diagram illustrates the usage of a memory buffer allocated via call to malloc from different modules
In the above diagram Module 1 is linked to CRT statically, while Modules 2 and 3 are linked to CRT dynamically. Modules 2 and 3 can pass CRT owned objects between them freely. For example, a memory chunk allocated with On the other hand, Module 1 cannot let other modules to free its resources. Everything allocated in Module 1 must be freed by Module 1. It is because only Module 1 has an access to statically linked instance of CRT. In the above sample Module 2 must remember to call a function from Module 1 in order to properly release acquired memory. 3.2 Linking DynamicallyWhen CRT/C++ Library linked dynamically, then only small import libraries are linked with resulting executable image. Import libraries conatin instructions where to find actual implementation of CRT/C++ Library functions. On program's start system loader reads these instructions and loads appropriate DLL's into process' address space. Advantages:
Disadvantages:
4. SummaryThe article described relationships and dependencies between Windows API, C Runtime Library and Standard C++ Library. Windows API is a lowest operational level for user mode programs. On top of Windows API there is C Runtime Library, which encapsulates and hides operating system differences. Standard C++ Library provides much more functionality and also includes CRT as an integral part. Using only standardized functions and classes allows to write cross-platform applications. Such applications require rebuild only in order to run on new platform. No code change is required. Both C Runtime Library and Standard C++ Library can be linked to statically or dynamically, depending on application's needs. Each method has its own advantages and drawbacks. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||