4.4.1
Freundlich's C++ toolkit
Loading...
Searching...
No Matches
Macros
fcppt.export

Description

Macros related to library visibility.

Introduction

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).

Note
Although every symbol can be made public under a POSIX system by default, this is still not recommended, because you have to specify the visibility for Windows anyway and libraries with only public symbols tend to have an unnecessarily large interface.

Defining library interfaces

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 .

#include <fcppt/symbol/export.hpp>
#include <fcppt/symbol/import.hpp>
// MYLIB_EXPORTS should be defined by the build system when the library is
// beign built. If other code includes the library's header, the macro will not
// be defined.
#if defined(MYLIB_EXPORTS)
#define MYLIB_SYMBOL FCPPT_SYMBOL_EXPORT
#else
#define MYLIB_SYMBOL FCPPT_SYMBOL_IMPORT
#endif

MYLIB_SYMBOL can then be used to export a function.

namespace mylib
{
// Conditionally export func
MYLIB_SYMBOL
void func();
}

The definition of the function doesn't need anything special.

void mylib::func() {}

Exporting a vtable of a class

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.

See also
FCPPT_SYMBOL_CLASS for a detailed explanation on when this is necessary.
#include <fcppt/symbol/class.hpp>
namespace mylib
{
// Export the vtable of someclass
// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
class FCPPT_SYMBOL_CLASS someclass
{
public:
// Also export its destructor
MYLIB_SYMBOL
virtual ~someclass();
};
}

List of things to export

Generally, every object with external linkage must be exported. This includes:

Compiler specific usage

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:

Static linking

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.

#include <fcppt/symbol/export.hpp>
#include <fcppt/symbol/import.hpp>
// If MYLIB_STATIC is defined, the library is being built or used as a static
// library. In this case we can't use any special symbols.
#if defined(MYLIB_STATIC)
#define MYLIB_SYMBOL
#elif defined(MYLIB_EXPORTS)
#define MYLIB_SYMBOL FCPPT_SYMBOL_EXPORT
#else
#define MYLIB_SYMBOL FCPPT_SYMBOL_IMPORT
#endif

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.

#include <fcppt/symbol/export_class_instantiation.hpp>
#include <fcppt/symbol/export_function_instantiation.hpp>
// Also, we have to leave the macros for explicit instantiations empty, if
// MYLIB_STATIC is defined.
#if defined(MYLIB_STATIC)
#define MYLIB_EXPORT_CLASS_INSTANTIATION
#define MYLIB_EXPORT_FUNCTION_INSTANTIATION
#else
#define MYLIB_EXPORT_CLASS_INSTANTIATION FCPPT_SYMBOL_EXPORT_CLASS_INSTANTIATION
#define MYLIB_EXPORT_FUNCTION_INSTANTIATION FCPPT_SYMBOL_EXPORT_FUNCTION_INSTANTIATION
#endif

Header files

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.
 

Macro Definition Documentation

◆ FCPPT_SYMBOL_CLASS

#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.

class FCPPT_DETAIL_SYMBOL_CLASS my_exception
{
};
class FCPPT_DETAIL_SYMBOL_CLASS my_base
{
virtual
void
do_something() = 0;
};
See also
Exporting a vtable of a class

◆ FCPPT_SYMBOL_EXPORT

#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.

See also
Defining library interfaces

◆ FCPPT_SYMBOL_EXPORT_CLASS_INSTANTIATION

#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.

See also
Defining library interfaces

◆ FCPPT_SYMBOL_EXPORT_FUNCTION_INSTANTIATION

#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.

See also
Defining library interfaces

◆ FCPPT_SYMBOL_IMPORT

#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.

See also
Defining library interfaces