The Simple Dynamic Class Loader library implements a dynamic loader facility for the C++ programming language. It allows applications to load dynamic classes, create objects from dynamically loaded classes, and dynamically access data member and member functions of those classes.
#include <sdl.h> // // loads class Employee from a dynamic library person.so // Class * employee_class = load_class("Employee", "person.so"); // // now you can use employee_class to create "Employee" objects // and to access their data members and member functions. //
This example alludes to a class called "Employee" loaded from a dynamic library called "person.so". The employee_class
object provides access to a set of constructor functions that can be used to create "Employee" objects. For example:
// // create an object of type Person // Object * antonio = employee_class.new_object("Antonio"); // // assign value to data member, and call methods // of the "Employee" class // antonio->int_attribute("salary") = 100; antonio->call("add_project", "Siena");
// // file employee.cc // #include <sdl.h> using namespace sdl; // // actual class declaration // class Employee { private: // ... public: int salary; void add_project(const string & project_name); // ... }; // // we must also define one or more constructor "helper" functions // static Employee * new_employee() { return new Employee(); } // // now we are ready to define the initialization function for the // Employee class // extern "C" Class * init_Employee() { // first we create a "wrapper" for our Employee class ConcreteClass<Employee> * e = new ConcreteClass<Employee>(); // then we add one or more constructor functions e->set_constructor(&new_employee); // then we add zero or more data members and/or member functions e->bind("salary", &Employee::salary); e->bind("add_project", &Employee::add_project); // finally, we return the class wrapper return e; }
This code must then be compiled into a dynamically loadable module, which must export the initialization function. The compilation for command might look like this:
g++ -I/opt/sdl/include -c employee.cc -fPIC -DPIC -o employee.o g++ -shared employee.o -L/opt/sdl/lib -lsdl -o employee.so
The compilation of loadable modules are very much system-dependent, and are therefore outside the scope of this documentation. For more information on compiling dynamically-loadable modules, please consult the libtool utility.
Obviously, the initialization mechanism used by this library is very similar to that of many other modular systems. The main idea is to hook into the dynamically-loaded class through an initialization function, which will be loaded by the operating system's dynamic loader, and executed by SDL. In particular, SDL adopts an initialization scheme whereby the initialization function is directly responsible for returning an interface to the dynamically-loaded class. So, the initialization function must be programmed as follows:
extern "C"
).
init_
class-name, where class-name is the name specified by the user with the load_class function.
Notice that the class-name used for the initialization function does not have to be the same as the actual class name (passed as a parameter to the ConcreteClass template). Similarly, the binding functions do not require that the name of the data members or member functions be consistent with the actual data member or member function. However, it is sensible practice to be consistent with those names.