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.
// 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.
};
};
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.