4.6.0
Freundlich's C++ toolkit
|
Macros related to library visibility.
When building a library, several platforms have different notions of library visibility that the library author has to consider. A symbol (like a function or global object) can be hidden in the library or it can be made public for other libraries or programs to use (for POSIX systems it is slightly more complex, but the two mentioned cases are the ones that really matter). Furthermore the library author has to specify whether a symbol is currently being exported or imported (because some platforms like Windows need this).
Several macros are provided to make a symbol public. Because it is necessary to specify whether a symbol is currently imported or exported, some additional work needs to be done by the library author and the build system to ensure that this is always correctly specified. The common way to do this is to define some kind of macro when the library is being built, which means the symbols are currently exported. This macro will not be defined in all other cases, which means the symbols are currently imported.
In the following example the macro MYLIB_EXPORTS
is defined by the build system if the library is currently being built. This macro is used to define MYLIB_SYMBOL
to either FCPPT_SYMBOL_EXPORT or FCPPT_SYMBOL_IMPORT .
MYLIB_SYMBOL
can then be used to export a function.
The definition of the function doesn't need anything special.
If a class's vtable needs to be exported, a special macro FCPPT_SYMBOL_CLASS must be used. This macro doesn't need to change whether the vtable is currently imported or exported.
Generally, every object with external linkage must be exported. This includes:
Functions (free or in a class), constructors and destructors which are defined inside the library need a conditional symbol like MYLIB_SYMBOL
at their declaration, and nothing special at their definition.
Objects with external linkage defined inside the library are handled like functions.
Classes that need their vtables to be exported must use FCPPT_SYMBOL_CLASS at their definition.
An explicitly instantiated template function needs everything that a normal function would need, but is also needs an FCPPT_SYMBOL_EXPORT_FUNCTION_INSTANTIATION at its explicit instantiation.
In the following example, a templated function is explicitly instantiated and exported. The function declaration needs a conditional symbol like MYLIB_SYMBOL
because a normal function would also need it.
The explicit instantiation needs an additional FCPPT_SYMBOL_EXPORT_FUNCTION_INSTANTIATION. It is important that this comes after the template
keyword but before the rest of the explicit function instantiation.
An explicitly instantiated template class is handled in a similarly to explicitly instantiated functions.
In the following example, a templated class is explicitly instantiated and exported. The class definition is, again, as if it was a normal class.
The explicit instantiation needs an additional FCPPT_SYMBOL_EXPORT_CLASS_INSTANTIATION. It must be placed after the class
or struct
keyword and before the rest of the type.
Library visibility is only useful if a shared library is being built and if the symbols of the shared library are hidden by default. Here is some advice how to use different build systems:
For gcc and clang, you should use the option -fvisibility=hidden
. Only then will all the symbols be hidden by default, so that making symbols public actually does anything.
gcc might ignore FCPPT_SYMBOL_EXPORT_FUNCTION_INSTANTIATION or FCPPT_SYMBOL_EXPORT_CLASS_INSTANTIATION if an implicit instantiation of the same type already took place in the same translation unit. You must ensure that this does not happen by creating separate translation units for every type you wish to explicitly instantiate and export.
For static linking to work, all of the attributes must be disabled. To do that, we are first going to introduce a macro MYLIB_STATIC
that is defined both when the static library is being built and when the library should be used statically.
You also have to make sure that the macros for explicit template instantiations are empty if MYLIB_STATIC
is defined. These two macros should be used instead of the ones provided by fcppt.
Header file | Description |
---|---|
symbol/export.hpp | Contains FCPPT_SYMBOL_EXPORT . |
symbol/import.hpp | Contains FCPPT_SYMBOL_IMPORT . |
symbol/class.hpp | Contains FCPPT_SYMBOL_CLASS . |
symbol/export_class_instantiation.hpp | Contains FCPPT_SYMBOL_EXPORT_CLASS_INSTANTIATION . |
symbol/export_function_instantiation.hpp | Contains FCPPT_SYMBOL_EXPORT_FUNCTION_INSTANTIATION . |
Macros | |
#define | FCPPT_SYMBOL_CLASS FCPPT_SYMBOL_CLASS_IMPL |
Tells that a classes's vtable should be exported. | |
#define | FCPPT_SYMBOL_EXPORT FCPPT_SYMBOL_EXPORT_IMPL |
Tells that a symbol should be exported. | |
#define | FCPPT_SYMBOL_EXPORT_CLASS_INSTANTIATION FCPPT_SYMBOL_EXPORT_CLASS_INSTANTIATION_IMPL |
Tells that an explicit class instantiation should be exported. | |
#define | FCPPT_SYMBOL_EXPORT_FUNCTION_INSTANTIATION FCPPT_SYMBOL_EXPORT |
Tells that an explicit function instantiation should be exported. | |
#define | FCPPT_SYMBOL_IMPORT FCPPT_SYMBOL_IMPORT_IMPL |
Tells that a symbol should be imported. | |
#define FCPPT_SYMBOL_CLASS FCPPT_SYMBOL_CLASS_IMPL |
Tells that a classes's vtable should be exported.
This macro marks a classes's vtable to be exported, so it can be shared across dynamic libraries. There are several cases in which this is necessary:
The class is thrown as an exception and caught by another library.
The class has virtual methods that will be called directly from another library.
It is not necessary to specify whether the class is currently exported or imported.
#define FCPPT_SYMBOL_EXPORT FCPPT_SYMBOL_EXPORT_IMPL |
Tells that a symbol should be exported.
This macro marks a symbol to be exported, so it can be used by other libraries or programs.
#define FCPPT_SYMBOL_EXPORT_CLASS_INSTANTIATION FCPPT_SYMBOL_EXPORT_CLASS_INSTANTIATION_IMPL |
Tells that an explicit class instantiation should be exported.
This macro marks an explicitly instantiated template class to be exported, so it can be used by other libraries or programs.
#define FCPPT_SYMBOL_EXPORT_FUNCTION_INSTANTIATION FCPPT_SYMBOL_EXPORT |
Tells that an explicit function instantiation should be exported.
This macro marks an explicitly instantiated template function to be exported, so it can be used by other libraries or programs.
#define FCPPT_SYMBOL_IMPORT FCPPT_SYMBOL_IMPORT_IMPL |
Tells that a symbol should be imported.
This macro marks a symbol to be imported, so it can be used from another library.