Parts:

PDOH - Overview

Preprocessor tags

PDOH triggers whenever it finds a //%%DYNOBJ tag in the source code. After the tag comes a directive and a number of attributes:

     // %% DYNOBJ directive(dval1,dval2) attr1(aval1,aval2,...) ...

The directive specifies what to look for or emit at this point in the source file. The most common one is class, which declares a plugin class type. From DoBaseI.h:

// %%DYNOBJ class(dyni) flags(inst2reg)
class NamedRefI : public DynI {
public:
   virtual DynObjType* docall doGetType( const DynI **pself=0 ) const;
   virtual DynI* docall GetByName( const char *name, int type_id );

In this example we instruct the preprocessor to look for a class declaration at the following line, and to generate type information for that class. The dyni value tells the preprocessor that this class derives from DynI (as opposed to independent of the DynObj class hierarchy).

The second attribute field flags can set a number of properties for the class. In this case we tell it that it is OK to instantiate an object of this type during registration.

Preprocessor output

At the start of the file (when using option -o), the preprocessor outputs the following based on the class(dyni) tag above:

// %%DYNOBJ section general
// --- Integer type ids for defined interfaces/classes ---
#define NAMEDREFI_TYPE_ID 0xAABF9000

// --- Forward class declarations ---
class NamedRefI;

// --- For each declared class, doTypeInfo template specializations ---
DO_DECL_TYPE_INFO(NamedRefI,NAMEDREFI_TYPE_ID);
// %%DYNOBJ section end

This code is used by both the host and the plugin to identify the C++ type with an integer type ID and a class name.

At the end of the file, also from the same tag, the following is generated:

// %%DYNOBJ section implement
// This section is auto-generated and manual changes will be lost when regenerated!!
#ifdef DO_IMPLEMENT_DOBASEI

DynObjTypeI2R<NamedRefI,DynI,false>
g_do_vtype_NamedRefI("NamedRefI:DynI",NAMEDREFI_TYPE_ID,1);

// Generate type information that auto-registers on module load
DynObjType* NamedRefI::doGetType( const DynI **pself ) const {
    if(pself) *pself=(const DynI*)(const void*)this;
    return &g_do_vtype_NamedRefI;
}
#endif //DO_IMPLEMENT_...
// %%DYNOBJ section end

The above section code that belongs in a source file. The define flag DO_IMPLEMENT_DOBASEI ensures the section is only included from a single place (from the plugin).

So we see that a fair bit of code is needed to glue make a plugin class useful, and PDOH generates most of this for us.