External Linkage Specification

Apache modules are compiled as separate compilation units from the Apache core and then either statically or dynamically linked to the core server. In order for the core server to interface with the module it must be able to find the module record (a special struct, the structure of which is defined by the API) within the module.

C and C++ compile to the same object code format on all systems but the way that the source code names are translated (mangled) to the symbol names in the object file is different in each language and may even be different from compiler to compiler. C generally names the symbol in the object file the same as the symbol in the source code (possibly prepending an "_"). C++ on the other hand must encode type information into the symbol name in order to preserve strong type safety across compilation units. It is hard and non-portable to predict C++ symbol names.

In order to link C++ object files to C programs it is neccessary to specially declare the external symbols which will be linked to the C code. These symbols will be mangled with C linkage specifications instead of C++ (ie no type safety). The keyword for making linkage specifications is extern. See the example for syntax.

The only symbol in the module which needs a C linkage specification is the module record itself. The rest of the functions may (and should) use C++ linkage specification (the default when you use a c++ compiler).

The documentation says that you only have to declare the declaration's linkage and that you do not have to use extern for the definition. This does not seem to be the case for the module record. It may be that this only applies to functions. In anycase it doesn't hurt to put the extern in both places.

Example

Source File

// We have to use C style linkage for the API functions that will be
// linked to apache.

// The declaration towards the beginning of the file
extern "C" module MODULE_VAR_EXPORT foo_module;

// And then the definition later on.
extern "C" {
    // Dispatch list for API hooks
    module MODULE_VAR_EXPORT fast3lpoad_module = {
        STANDARD_MODULE_STUFF,
        // Fill the rest of this out as normal.
    };
};
    

External Documentation

The following is from the C++ FAQ Lite section titled How to mix C and C++:

[29.6] How can I create a C++ function f(int,char,float) that is callable by my C code?

The C++ compiler must know that f(int,char,float) is to be called by a C compiler using the extern C construct:

    // This is C++ code
    
    
// Declare f(int,char,float) using extern C:
    extern "C" void f(int i, char c, float x);
    
    
// ...
    
    
// Define f(int,char,float) in some C++ module:
    void f(int i, char c, float x)
    {
      
// ...
    }

The extern C line tells the compiler that the external information sent to the linker should use C calling conventions and name mangling (e.g., preceded by a single underscore). Since name overloading isn't supported by C, you can't make several overloaded functions simultaneously callable by a C program.


Zachary C. Miller
Last modified: Tue Sep 14 02:02:25 CDT 1999