1.Using extern to Specify Linkage
Syntax
linkage-specification :
extern declarator
extern string-literal { declaration-listopt }
extern string-literal declaration
declaration-list :
declaration
declaration-list declaration
The extern keyword declares a variable or function and specifies that it has external linkage (its name is visible from files other than the one in which it's defined). When modifying a variable, extern specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends). The variable or function may be defined in another source file, or later in the same file. Declarations of variables and functions at file scope are external by default.
For example:
int i = 1;
void other( void );
void main(){
/* Reference to i, defined above: */
extern int i;
return;
}
void other( void ){
/* Address of global i assigned to pointer variable: */
static int *external_i = &i;
/* i is redefined; global i no longer visible: */
int i = 16;
In C++, when used with a string, extern specifies that the linkage conventions of another language are being used for the declarator(s). C functions and data can be accessed only if they are previously declared as having C linkage. However, they must be defined in a separately compiled translation unit.
Microsoft C++ supports the strings "C" and "C++" in the string-literal field. All of the standard include files use the extern "C" syntax to allow the run-time library functions to be used in C++ programs.
The following example shows alternative ways to declare names that have C linkage:
// Declare printf with C linkage.
extern "C" int printf( const char *fmt, ... );
// Cause everything in the header file "cinclude.h"
// to have C linkage.
extern "C"
{
#include <cinclude.h>
}
// Declare the two functions ShowChar and GetChar
// with C linkage.
extern "C"
{
char ShowChar( char ch );
char GetChar( void );
}
// Define the two functions ShowChar and GetChar
// with C linkage.
extern "C" char ShowChar( char ch )
{
putchar( ch );
return ch;
}
extern "C" char GetChar( void )
{
char ch;
ch = getchar();
return ch;
}
// Declare a global variable, errno, with C linkage.
extern "C" int errno;
2.Linkage Specifications
The term “linkage specification” refers to the protocol for linking functions (or procedures) written in different languages. The following calling conventions are affected:
- Case sensitivity of names.
- Decoration of names. In C, the compiler prefixes names with an underscore. This is often called “decoration.” In C++, name decoration is used to retain type information through the linkage phase.
- Order in which arguments are expected on the stack.
- Responsibility for adjusting the stack on function return. Either the called function or the calling function is responsible.
- Passing of hidden arguments (whether any hidden arguments are passed).
Syntax
-
linkage-specification :
-
extern
string-literal
{
declaration-list
opt
}
extern string-literal declaration
declaration-list :
-
declaration
declaration-list
Linkage specification facilitates gradually porting C code to C++ by allowing the use of existing code.
Microsoft Specific
The only linkage specifications currently supported by Microsoft C++ are "C" and "C++".
END Microsoft Specific
The following example declares the functions atoi
and atol
with C linkage:
extern "C" { int atoi( char *string ); long atol( char *string ); }
Calls to these functions are made using C linkage. The same result could be achieved with these two declarations:
extern "C" int atoi( char *string ); extern "C" long atol( char *string );
Microsoft Specific
All Microsoft C standard include files use conditional compilation directives to detect C++ compilation. When a C++ compilation is detected, the prototypes are enclosed in an extern "C" directive as follows:
// Sample.h #if defined(__cplusplus) extern "C" { #endif // Function declarations #if defined(__cplusplus) } #endif
END Microsoft Specific
You do not need to declare the functions in the standard include files as extern "C".
If a function is overloaded, no more than one of the functions of the same name can have a linkage specifier. (For more information, see Function Overloading in Chapter 7.)
Table 6.3 shows how various linkage specifications work.
Table 6.3 Effects of Linkage Specifications
Specification | Effect |
On an object | Affects linkage of that object only |
On a function | Affects linkage of that function and all functions or objects declared within it |
On a class | Affects linkage of all nonmember functions and objects declared within the class |
If a function has more than one linkage specification, they must agree; it is an error to declare functions as having both C and C++ linkage. Furthermore, if two declarations for a function occur in a program — one with a linkage specification and one without — the declaration with the linkage specification must be first. Any redundant declarations of functions that already have linkage specification are given the linkage specified in the first declaration. For example:
extern "C" int CFunc1(); ... int CFunc1(); // Redeclaration is benign; C linkage is // retained. int CFunc2(); ... extern "C" int CFunc2(); // Error: not the first declaration of // CFunc2; cannot contain linkage // specifier.
Functions and objects explicitly declared as static within the body of a compound linkage specifier ({ }) are treated as static functions or objects; the linkage specifier is ignored. Other functions and objects behave as if declared using the extern keyword. (See Using extern to Specify Linkage for details about the extern keyword.)
3.Linkage
Identifier names can refer to different identifiers in different scopes. An identifier declared in different scopes or in the same scope more than once can be made to refer to the same identifier or function by a process called “linkage.” Linkage determines the portions of the program in which an identifier can be referenced (its “visibility”). There are three kinds of linkage: internal, external, and no linkage.
4.CCriticalSection
A CCriticalSection object represents a critical section, which is a synchronization object that allows one thread at a time to access a resource or section of code. Critical sections are useful when only one thread at a time can be allowed to modify data or some other controlled resource. For example, adding nodes to a linked list is a process that should only be allowed by one thread at a time. By using a CCriticalSection object to control the linked list, only one thread at a time can gain access to the list.
The functionality of the CCriticalSection class is provided by an actual Windows CE CRITICAL_SECTION object.
Critical sections are used instead of mutexes when speed is critical and the resource will not be used across process boundaries. For more information on mutexes, see CMutex.
There are two methods for using a CCriticalSection object: stand-alone or embedded in a class.
To use a stand-alone CCriticalSection object, construct the CCriticalSection object when it is needed. After a successful return from the constructor, explicitly lock the object with a call to Lock. Call Unlock when you finish accessing the critical section. This method, while clearer to someone reading your source code, is more prone to error because you must remember to lock and unlock the critical section before and after access.
You can also share a class with multiple threads by adding a CCriticalSection-type data member to the class and locking the data member when needed.