Listing 2

// The DynamicLibrary class.
// This class will be created by the dynamic loader, 
// and can be used to create objects out of a loaded library
class DynamicLibrary
{
    protected:
        // The handle to the shared library that was opened
        void* _objFile;
        // Since an instance of DynamicLibrary manages lifetime of an open 
        // library, it is important to make sure that the object isn't 
        // copied.
        DynamicLibrary(const DynamicLibrary&) {}
        DynamicLibrary& operator=(const DynamicLibrary&) {}

        // Creates a new library, with the object file handle that is passed 
        // in. Protected so that only the DynamicLoader can create an 
        // instance (since it is declared friend.
        DynamicLibrary(void* objFile);
    public:
        // Destructor, closes the open shared library
        ~DynamicLibrary(void);

        // Creates a new instance of the named class, or returns NULL is the 
        // class isn't found. The array of void*'s takes the arguments for   
        // the class's constructor, with argc giving the number of arguments.
        DynamicObject* newObject(const char* name, int argc, void** argv);

        // Declare the DynamicLoader as a friend, so it can
        // instantiate DynamicLibrary.
        friend class DynamicLoader;
};
// The dynamic loader class, used for loading DynamicLibraries.
class DynamicLoader
{
    public:
        // Loads a DynamicLibrary, given the shared library file
        // "file", with the dlopen flags supplied.
};
DynamicLibrary::DynamicLibrary(void* objFile)
    : _objFile(objFile)
{
}
DynamicLibrary::~DynamicLibrary(void)
{
    dlclose(_objFile);
}
DynamicObject*
DynamicLibrary::newObject(const char* name, int argc, void** argv)
{
    // If there is no valid library, return null
    if(_objFile == NULL) {
        return NULL;
    }
    // Get the loadObject() function.  If it doesn't exist, return NULL.
    void* loadSym = dlsym(_objFile, "loadObject");
    if(loadSym == NULL) {
        return NULL;
    }
    // Load a new instance of the requested class, and return it
    void* obj = 
      ((void* (*)(const char*, int, void**))(loadSym))(name, argc, argv);
    return reinterpret_cast<DynamicObject*>(obj);
}
DynamicLibrary*
DynamicLoader::loadObjectFile(char* file, int flags)
{
    void* objFile = dlopen(file, flags);
    if(objFile == NULL) {
        return NULL
    }
    return new DynamicLibrary(objFile);
}