nidas
v1.2-1520
|
Class that supports creating instances of DOMable objects from a string containing the class name of the object to be created. More...
#include <DOMObjectFactory.h>
Public Types | |
typedef DOMable * | dom_object_ctor_t () |
Prototype of the creator function. More... | |
Static Public Member Functions | |
static DOMable * | createObject (const std::string &classname) throw (nidas::util::Exception) |
Create a DOMable object given its classname , by looking up and executing its creator function, typically from a shared library. More... | |
Static Public Attributes | |
static const char * | soVersionSuffix = ".so.1" |
When searching for libraries based on the class name, add this suffix to the name. More... | |
Class that supports creating instances of DOMable objects from a string containing the class name of the object to be created.
Classes can be dynamically loaded from shared libraries.
typedef DOMable* nidas::core::DOMObjectFactory::dom_object_ctor_t() |
Prototype of the creator function.
|
static |
Create a DOMable object given its classname
, by looking up and executing its creator function, typically from a shared library.
In order to be created via this method, an object's class must have the following characteristics:
If it were possible to know how C++ mangles the name of a constructor then we could dynamically lookup and execute the default constuctor directly. There isn't a standard for name mangling and I don't know of an API for determining a mangled name, so we create and lookup a C creator function using our own mangling scheme.
For example, if the following class exists in a shareable library, and is derived from DOMable, with a no-arg constructor: nidas::dynld::MyNameSpace::MyClass
there then must also be an extern "C" creator function called: create_nidas_dynld_MyNamespace_MyClass
The C function can be defined with this macro: NIDAS_CREATOR_FUNCTION_NS(MyNameSpace,MyClass)
The classname
string argument passed to this createDOMObject() method doesn't contain the leading "nidas::dynld" namespace qualifier, and can be specified in C++ style with "::" delimiters: "MyNameSpace::MyClass"
or Java style, with "." delimiters: "MyNameSpace.MyClass"
If the class is in the nidas::dynld namespace, the example above becomes: nidas::dynld::MyClass
Extern "C" function: create_nidas_dynld_MyClass
Macro to define the C function: NIDAS_CREATOR_FUNCTION(MyClass)
classname
argument to this method: "MyClass"
The name of the creator function is mangled from the classname
argument as follows. The given classname
is converted by appending it to nidas_dynld_
, and all occurrences of double-colons (::) and periods (.) are replaced with * underscores (_). Then create_
is prepended to the converted class name.
The extern "C" function can be either statically linked in the program, or in a shareable library. createObject() attempts to resolve the extern "C" function symbol via the following search:
.so suffix to DynamicLoader::lookup(library,name). Using the first example above, the dynamic loader would look for a library called nidas_dynld_MyNameSpace_MyClass.so
.lib
to the name, and appending soVersionSuffix
. Using the first example the loader would search the following libraries in order:libnidas_dynld_MyNameSpace.so.1
libnidas_dynld.so.1
assuming that soVersionSuffix was set to ".so.1" in this class.After being created by this method, then the attributes of the object are typically filled in from an XML DOM element via virtual nidas::core::DOMable::fromDOMElement() method.
References DLOG, nidas::core::DynamicLoader::getInstance(), nidas::core::DynamicLoader::lookup(), and nidas::util::Exception::what().
Referenced by nidas::core::IOChannel::createIOChannel(), nidas::core::VariableConverter::createVariableConverter(), nidas::core::DSMServer::fromDOMElement(), nidas::core::DSMService::fromDOMElement(), nidas::core::DSMConfig::fromDOMElement(), nidas::core::SampleIOProcessor::fromDOMElement(), nidas::core::Project::fromDOMElement(), and nidas::core::DSMConfig::sensorFromDOMElement().
|
static |
When searching for libraries based on the class name, add this suffix to the name.
Typically something like ".so.1". This may need more thought. The idea is not to use just ".so", without a version number, since that typically refers to symbolic links found only in -devel packages. Would be nice for this to be set somehow by the build system.