EPICS Base  7.0.6.1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Macros
shareLib.h File Reference

Mark external symbols and entry points for shared libraries. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define epicsShareExtern   extern
 
#define epicsShareAPI
 
#define epicsShareClass
 
#define epicsShareDef
 
#define epicsShareFunc
 
#define READONLY   const
 
#define INLINE_defs_EPICS
 

Detailed Description

This is the header file for the "decorated names" that appear in header files, e.g.

#define epicsExportSharedSymbols
epicsShareFunc int epicsShareAPI a_func(int arg);

These are needed to properly create DLLs on MS Windows.

USAGE

There are two distinct classes of keywords in this file:

  1. epicsShareAPI - specifies a multi-language calling mechanism. On windows this is the pascal calling convention which is used by visual basic and other high level tools. This is only necessary if a C/C++ function needs to be called from other languages or from high level tools. The epicsShareAPI keyword must be present between the function's returned data type and the function's name. All compilers targeting windows accept the __stdcall keyword in this location. Functions with variable argument lists should not use the epicsShareAPI keyword because __stdcall (pascal) calling convention cannot support variable length ed argument lists.

    int epicsShareAPI myExtFunc ( int arg );
    int epicsShareAPI myExtFunc ( int arg ) {}
    
    Note
    The epicsShareAPI attribute is deprecated and has been removed from all IOC-specific APIs. Most libCom APIs still use it, but it may get removed from these at some point in the future.
  2. epicsShare{Func,Class,Extern,Def} - specifies shareable library (DLL) export/import related information in the source code. On windows these keywords allow faster dispatching of calls to DLLs because more is known at compile time. It is also not necessary to maintain a linker input files specifying the DLL entry points. This maintenance can be more laborious with C++ decorated symbol names. These keywords are only necessary if the address of a function or data internal to a shareable library (DLL) needs to be visible outside of this shareable library (DLL). All compilers targeting windows accept the __declspec(dllexport) and __declspec(dllimport) keywords. For GCC version 4 and above the first three keywords specify a visibility attribute of "default", which marks the symbol as exported even when gcc is given the option -fvisibility=hidden. Doing this can significantly reduce the number of symbols exported to a shared library. See the URL below for more information.

In header files declare references to externally visible variables, classes and functions like this:

#include "shareLib.h"
epicsShareFunc int myExtFunc ( int arg );
epicsShareExtern int myExtVar;
class epicsShareClass myClass { int func ( void ); };

In the implementation file, however, you write:

#include <interfaces_imported_from_other_shareable_libraries.h>
#define epicsExportSharedSymbols
#include <interfaces_implemented_in_this_shareable_library.h>

epicsShareDef int myExtVar = 4;
int myExtFunc ( int arg ) {}
int myClass::func ( void ) {}

By default shareLib.h sets the DLL import / export keywords to import from a DLL so that, for DLL consumers (users), nothing special must be done. However, DLL implementers must set epicsExportSharedSymbols as above to specify which functions are exported from the DLL and which of them are imported from other DLLs.

You must first #include what you import and then #define epicsExportSharedSymbols only right before you #include the prototypes for what you implement! You must include shareLib.h again each time that the state of the import/export keywords changes, but this usually occurs as a side effect of including the shareable libraries header file(s).

Deprecated Usage

The construct described below is used in some EPICS header files bit is no longer recommended as it makes it difficult to diagnose the incorrect inclusion of headers that are the wrong side of an epicsExportSharedSymbols marker.

Sometimes a header file for a shareable library exported interface will have some preprocessor switches like this if this header file must also include header files describing interfaces to other shareable libraries.

#ifdef epicsExportSharedSymbols
#   define interfacePDQ_epicsExportSharedSymbols
#   undef epicsExportSharedSymbols
#endif

#include "epicsTypes.h"
#include "epicsTime.h"

#ifdef interfacePDQ_epicsExportSharedSymbols
#   define epicsExportSharedSymbols
#   include "shareLib.h"
#endif

epicsShareFunc int myExtFunc ( int arg );
epicsShareExtern int myExtVar;
class epicsShareClass myClass {};

Fortunately, the above is only the concern of library authors and will have no impact on persons using functions and or external data from a library.

Definition in file shareLib.h.