|#define||DO_LIB_DESCR "No description"|
The macro DI_GET_TYPE() retrieves the type of a DynI. In the case of the instance being a side base (in a multiple base class object), the method DynI::doGetType depends on the VTable being 'corrected' (in doConstruct), otherwise, the compound object type is (incorrectly) returned. The call DynI::doGetType simply returns a global variable, where as doGetType(pdi) has to do a lookup in a hash table.
Means we're using the global function to get type
Defines what to do for assertions inside the DynObj library.
Automatically defined from DynObj.cpp
This is an alternative way of doing above, allowing for using a customized include filename for the settings.
|#define DO_DENY_EARLY_UNLOAD 0|
By default a library may be unloaded if DoRunTime sees no instantiated objects for the library, or, if all instantiated objects are safely trackable. However a library that for other reasons (such as exposing non trackable instances (globals) that DoRunTime does not see) we can make a library reject early unload requests. Default: 0 (better to make all instances always safely trackable)
|#define DO_ENABLE_OBJECT_TRACKING 1|
This option enables a DynObjLib to keep track of the number of objects it has created and know if there are still instances around on library unload. It requires DO_FAT_VOBJ since it depends on a trigger in the DynObj destructor. When the main application activates it at run-time, it has some cost in terms of memory and performance. Implementation depends on DoRunTime. Default: 1 if both DO_FAT_VOBJ and DO_USE_RUNTIME, else 0
|#define DO_ENABLE_OPERATOR_DELETE 0|
One can implement an operator delete inside DynObj to route this call doDestroy. Similarly, one can do the same to give an error for DynI. This works when there is no other customized operator delete at work. But when using a custom memory allocator, this scheme might not work anymore. It is best to delete DynObjs using doDestroy directly. Default: 0.
|#define DO_ENABLE_VTABLE_CORR 0|
When using several base classes, virtual functions of the bases are 'swallowed' by the compound class if it defines them. In C++ no selective function overriding is available, and a side-base class cannot prevent a derived class from overriding.
With VTable correction, this can be undone at run-time, efficiently letting base classes maintain 'local virtual' methods. It requires allocating and installing a new VTable for the object and this can break compiler specific usage of VTables (for this particular class) (this would usually be ordinary RTTI and potentially exception handling).
It enables more efficient type lookups, since we can be sure to get the type of the local sub-object, not the type of the full object.
It only affects side base classes when using multiple inheritance. VTables of other classes are untouched.
Default: 0 - not used
|#define DO_ENABLE_VTABLE_DISPATCH 0|
Function call convention. How function parameters are passed and how the stack is cleaned up after a function call. We define the macro docall to be used in each virtual function declaration.
On Unices, __cdecl is the default and does not have to be specified so docall is set to an empty value.
On Windows, it is best to use __cdecl (parameters pushed right-to-left, caller clears the stack). In particular, with MSVCm this has to be used to avoid member functions with __thiscall convention.
Alternatives are __stdcall, __fastcall, __thiscall __stdcall is used for script language calls on Win32 __fastcall is compiler dependent
Default: __cdecl on Windows, empty on Unices This enables invoking member functions using the VTable directly, as opposed to using it indirectly through the compiler. Methods are called by looking them up in the VTable using the method index. Currently only used for casts based on string when calling DynI::doGetType on side bases. It causes dependency on SpinLock.cpp. Default: 0
|#define DO_FAT_VOBJ 1|
This symbol allows for collectying all custom options defined for DynObj into a single file: DoSetup-custom.h. It can contain library name, autohor and any customization options for the library otherwise defined below.
|#define DO_LIB_AUTHOR "Anonymous"|
Defines name of library author
|#define DO_LIB_DESCR "No description"|
Description of plugin library
|#define DO_LIB_MAJOR_VERSION 0|
Defines the library major version
|#define DO_LIB_MINOR_VERSION 50|
Defines the library minor version
|#define DO_LIB_NAME "__auto__"|
Defines the name of the library being compiled. The name is platform independent and usually coincides with stripped name of a DLL/SO, i.e the name "DBase" corresponds to "DBase.dll" and libDBase.so
|#define DO_LOG2_NR_TYPES 5|
This constant is used for determining hash table size during base type linking phase. It should be approximately log2(types) so 5 is good for a library with about 20..50 types. The right constant speeds up this linking phase slightly.
Must be set when building a module
|#define DO_NO_TYPEINFO 0|
The doTypeInfo template enables going from C++ type to a type name and type ID. This macro can turn off that ability, to save some memory and reduce global symbol usage. However, then do_cast<Type> and DynI::Cast<Type> will not work. Default: 0
|#define DO_RETURN_STRUCT_WITH_DTOR_SAFE 1|
One safe way of returning a pointer to a created object is to return a wrapping object that holds the pointer to the new object and destroyes it when the wrapper goes out of scope. The application has to grab the pointer before this and thus take over ownership.
To do this, the compilers must be compatible in the way they handle returning of small structs (with destructors). The common way is for the compilers to add a 'hidden' first argument, a pointer where the return struct is stored.
|#define DO_THREADED 0|
If we're using DynObjs from threads or not. Default: 0
|#define DO_USE_DYNSHARED 1|
If we should use the class DynSharedI or not. It implements ref-counted ownership and adds little overhead. It depends on pi/Atomic.cpp). Default: 1
|#define DO_USE_NOTIFIER 0|
Whether we should use weak references in DynObjHolder or not. We get dependency on utils/Notifiable.cpp and pi/RWLock.cpp. From a main app with DO_USE_RUNTIME, it is automatically defined. Default: 1 if we use DoRunTime and if we are main, else 0
|#define DO_USE_RUNTIME 1|
If we should use the class DoRunTimeI or not. When using several DynObj libraries at the same time, DoRunTime provides useful functionality. It has global type database (making sure types can be resolved across library boundaries), it has a shared named object pool, it keeps track of per-object errors. For a library, using DoRunTimeI does not consume resources, since the instance will be with the main application. Default: 1 for both app & module
|#define DO_USE_TEMPLATES 1|
This can be used by implemented classes to query wheter C++ templates (such as do_cast) should be used. An ancient C++ compiler might not support templates as used in DoBase.hpp and friends.
Handle virtual destructors in VTables. A DynObj instance does not rely on virtual destructors. If a class with a virtual destructor has to be exposed as a DynObj, then, to another module, chances are that two different compilers use the entrie(s) in the VTable in slightly different ways.
Therefore it is best not to invoke virtual destructors on DynObj:s. Calling doDestroy gives the job of destroying the object to the module which created it. It knows how to use the destructors.
Also since some compilers (g++, others?) use two VTable slots for a virtual destructor and most other compiler only one, we have to compensate for that. The macro below can be pasted into an exposed class to make sure the VTables will have the same size regardless of compiler.
Add other compilers here.