Dynamic Class Loading for C++ on Linux
Recently, I have had two occasions to use this technique. In the first case, I was developing a moving object simulation. I wanted to provide users with the ability to add new types of moving objects without having access to the main source. In order to accomplish this, I defined a base class called entity, which provides the interface definition for any moving object in the simulation. A simplified version of the entity prototype is shown below.
class entity {
private:
float xyz[3]; // position of the object
public:
activate(float)=0; // tell the object to move
render()=0; // tell the object to draw itself
};
Thus, all entities have at least a position in three-space, and all entities can draw themselves. Most entities will have many other state variables besides position and may have many other member functions besides activate and render, but these are not accessible through the entity interface.
New entity types can be defined, incorporating whatever motion dynamics the user desires. At runtime, the program loads all the libraries in a subdirectory called Entity and makes them available to the simulation.
The second example comes from a recent project in which we wanted to create a library that could load and save images of various formats. We wanted the library to be extensible, so we created a base image_handler class for loading and saving images.
class image_handler{
public:
virtual Image loadImage(char *)=0;
virtual int saveImage(char *, Image &)=0;
};
The image_handler has two public functions, used to load and save images, respectively. The Image class is the library's basic object type for images. It provides access to the image data and some basic image-manipulation functions.
In this case, we were not interested in creating multiple objects of each type of image_handler. Instead, we wanted one instance of each image_handler that would handle loading and saving images of that type. Rather than registering a maker for each handler, we created a single instance of the handler in its library and registered a pointer to it with a global map. The map is no longer a factory, since it does not produce objects per se; it is more of a generic image loader/saver. The keys used here were strings representing file extensions (tif, jpg, etc.). Because a file format can have one of several different extensions (e.g., tiff, TIFF), each handler registers itself multiple times with the global map, once for each extension.
Using the library, a main program can load or save an image simply by invoking the correct handler via the file extension:
map <string, handler, less<string>> handler_map;
char *filename = "flower.tiff";
char ext[MAX_EXT_LEN];
howEverYouWantToParseTheExtensions(filename, ext);<\n>
// after parsing "flower.tiff" ext = "tiff"<\n>
Image img1 = handler_map[ext]->loadImage(filename);
// process data here
handler_map[ext]->saveImage(filename, img1);
Dynamic class loading allows us to create more extensible and more robust code. By using dynamic class loading combined with well-thought-out base class designs, we provide users with a practical means of extending our code.

- « first
- ‹ previous
- 1
- 2
- 3
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.
Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.
Sponsored by ActiveState
| Speed Up Your Web Site with Varnish | Jun 19, 2013 |
| Non-Linux FOSS: libnotify, OS X Style | Jun 18, 2013 |
| Containers—Not Virtual Machines—Are the Future Cloud | Jun 17, 2013 |
| Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer | Jun 12, 2013 |
| Weechat, Irssi's Little Brother | Jun 11, 2013 |
| One Tail Just Isn't Enough | Jun 07, 2013 |
- Speed Up Your Web Site with Varnish
- Containers—Not Virtual Machines—Are the Future Cloud
- Linux Systems Administrator
- Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer
- Non-Linux FOSS: libnotify, OS X Style
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- RSS Feeds
- Reply to comment | Linux Journal
1 hour 44 min ago - Reply to comment | Linux Journal
5 hours 44 min ago - Yeah, user namespaces are
7 hours 37 sec ago - Cari Uang
10 hours 31 min ago - user namespaces
13 hours 25 min ago - yea
13 hours 51 min ago - One advantage with VMs
16 hours 19 min ago - about info
16 hours 52 min ago - info
16 hours 53 min ago - info
16 hours 54 min ago
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
dependencies
And what about depencies of dynamically loaded libs ?
I've got this pb :
I load dynamically some personal lib as you showed. But some objects of this lib also load some other lib dynamically. Those libs have direct dependencies with the root one , and when I dlopen them, I've got an error telling that dlopen tries to load the root lib (which is not in classical dirs, I loaded it with absolute path) and can't find it.
please if someone can help.
hi... i need to create the
hi... i need to create the member variables in a class at runtime... also these variables should be defined by a config file... is it possible .. can anyone help ...
You mean shape *my_circle
You mean
shape *my_circle = factory["circle"]();
rather than
shape *my_circle = factory["circle"];
Nice article. :-)
Cpp
A very good finding for me. I developed a good amount of code in C but i'm new to cpp. I feel familiar with the dynamic libraries in cpp now. ThanQ.
Very useful
This article was perfect, for not just learning basic dynamic module loading, but also the clever, clean technique for autoregistration. Everything worked beautifully for my project right away
Thank you for the article
Great article and easy to follow. This is exactly the sort of information I was looking for. I've previously written a large application in C which used dynamic modules, but I've been digging around to find the "proper" way to do the same thing in C++. This article cut right to the chase.
Nice Article
Hi ! Just wanted to say thanks for the nice article. Just tried it with g++ 4.xx. Works nearly out of the box... If you have more than one "shape" that you want to add, I would add static to the definitions of the maker function and the proxy p. This saves you from renaming it in every file.
It's all so wrong
Factories, functions to access libraries, classes with textual names at runtime
It's all so wrong
C++ ! !
YECCCH !
I feel soiled just reading about it
And I feel dumber for having
And I feel dumber for having read your comment. :-(
very constructive comment!
probably from a .net zealot!
I actually like this article if only for the learning experience.
usage with Automake
I tried to include the above code into our project using automake.
Since i am building the libs in -> src/entities/Makefile.am all the .so files go directly to src/entities/.libs/*.so
when i make a 'make install' the libs go to /usr/local/lib/*.so (or somewhere else)
now if my program in src/program wants to open the libs, it does not know in what path to search (i have to add it by using: dlopen("src/entities/.libs/module.so", RT_NOW);)
Since i think that Automake should provide a facility for the 'searchpath', and i am absolutely unable to find it:
DOES ANYONE know ho to do this??
any help is appreciated
Anybody could provide a
Anybody could provide a working Makefile?, I can not understand how such a nice article can have this Makefile...
Makefile: You have to type
Makefile: You have to type for each '=>'. Save this file as Makefile and run with make.
CC = g++
LIBS = -ldl
.cc.o:
=>$(CC) -ggdb -c $<
default:
=>make main
OBJS = testdcl.o
main: main.o
=>$(CC) -rdynamic -o main main.o $(LIBS)
libcircle.so: circle.o
=>g++ -shared -Wl,-soname,libcircle.so -o libcircle.so circle.o
libsquare.so: square.o
=>g++ -shared -Wl,-soname,libsquare.so -o libsquare.so square.o
all: main libcircle.so libsquare.so
clean:
=>rm -f *.so *.o main
management of vtable
Hi,
I just want to know the how does this manages the vtable after laoding the class dynamically ?
Re: Dynamic Class Loading for C++ on Linux
Well, it's work fine for me (Gentoo Linux). But now I've tried to write a programm for a Solaris based system ... and the linker gives me some errors. So there must be a way to get it running, cause the compiler knows the dlopen(), dlsym() methods ... but the linker gives me errors.
Perhaps anybody can give me some hints ?
(Compiler : g++ 3.3)
Cross-platform loading of libraries.
Is there any library that I can use to dynamically load C-libraries on LINUX and WINDOWs both?
I tried Libtool's libltdl library, but it doesnt seem to work on WINDOWS (VC++).
Re: Cross-platform loading of libraries.
Eh? Windows has LoadLibrary() and GetProcAddress() which are nearly identical to dlopen() and dlsym() respectively.
Just make simple proxy functions that will use whichever method is appropriate for the proform it was compiled on.
Pseudo code:
LoadDynamicLibrary(char *path)
{
#ifdef _WIN32
LoadLibrary(path);
#else
dlopen(path);
#endif
}
can you create an object (of
can you create an object (of a class in the dll) using GetProcAddress? pls help...
Re: Cross-platform loading of libraries.
If you're writing a Qt application, you have the QLibrary class that OS independent resolves symbols from .so's resp. .dll's.
Re: Dynamic Class Loading for C++ on Linux
FYI you cannot throw, with ELF/linux under gcc 3.2.3, within the autoregistration proxy class constructor. So your constructor, as in the above example, is implicitly:
class proxy {
public:
proxy() throw() {
factory["shape name"] = maker;
}
};
Re: Dynamic Class Loading for C++ on Linux
It's a good article!!
I can compile your codes wih gcc-2.96 (rh7.2), but no luck with gcc-3.2. I'm a newbir on C++. So, can you make a version that can be compiled with gcc-3.2.
Thx
Re: Dynamic Class Loading for C++ on Linux
Oh yeah, almost forgot, you also want to make sure you don't forget to add the -ldl flag as a g++ command line argument. That tells the linker it should load the library you need to execute the dlxxxx series calls.
Cheers,
tundog
Re: Dynamic Class Loading for C++ on Linux
I had some trouble using gcc-3.2 as well. I couldn't get it to work with the static_cast syntax.
Instead of:
shape *my_shape = static_cast(mkr)();
Try using:
shape *my_shape = ((shape*(*)())(mkr))();
Cheers,
tundog
You can use reinterpret_cast
You can use reinterpret_cast instead of static_cast. This works for me.
Re: Dynamic Class Loading for C++ on Linux
XPLC does all of this, faster, better, simpler, safer.
http://xplc.sourceforge.net/
xplc is 0.3.0 Alpha
I presume that's why more stable is missing on your list of properties...
Re: xplc is 0.3.0 Alpha
Well, this is just some dlopen() sample code in an article, it's not like it's exactly a solid framework either...
Re: Dynamic Class Loading for C++ on Linux
bull***** it does.. lol
Re: Dynamic Class Loading for C++ on Linux
Is there any particular reason why deleting objects is omitted?
Re: Dynamic Class Loading for C++ on Linux
Wow, this works great, but I did run into one problem. I have a shape class which declares a draw() method. I can dynamically load the circle and square classes (which inherit from shape) and get polymorphic behavior. However, this only works if shape defines draw() as an empty method as opposed to a pure virtual method. If I try to declare draw() as a pure method I get an error during dlopen() that says "undefined symbol: __pure_virtual".
Is there a way I can get around this?
Thanks
Re: Dynamic Class Loading for C++ on Linux
That factory is nice idea but there are some problems with it:
Re: Dynamic Class Loading for C++ on Linux
While most of what you say is applicable to my situation, there is one main assumption that you've used... The base class has to be fixed, and dynamically loaded class has no knowledge of the classes in which it has just been instantiated with.
Re: Dynamic Class Loading for C++ on Linux
#######################
Error while executing the above program of shape :::
In function `int main ()':
m.C:22: cannot dynamic_cast `mkr' (of type `void *') to type `class
shape *' (source is not a pointer to class)
Can any one help me ????
I found out what the problem
I found out what the problem is. POSIX requires dlsym to return an object pointer while C++ requres that object pointers cannot be cast into function pointers. (This is because some systems have different pointer sizes for objects and functions.) The following union hack should work.
template<class TYPE>
TYPE function_cast(void * symbol)
{
assert(sizeof(void *) == sizeof(TYPE));
union
{
void * symbol;
TYPE function;
} cast;
cast.symbol = symbol;
return cast.function;
}
Then you should be able to cast to any pointer-to-function type, for exampe:
shape * my_shape = function_cast<shape(*)()>(mkr)();
A minor correction:
A minor correction:
shape * my_shape = function_cast(mkr)();
A correction of my
A correction of my correction:
shape * my_shape = function_cast(mkr)();
Re: Dynamic Class Loading for C++ on Linux
Hi,
You can try this way :
shape *(*mkr)()= (shape*(*)())dlsym(dlib, "maker");
shape *my_shape = (*mkr)();
my_shape->draw();
Re: Dynamic Class Loading for C++ on Linux
I too had alot of trouble getting this to compile. So I got the mini-dlopen example to work. Then, I came back to this one and it worked immediately after I re-downloaded it. So keep persevering!
Re: Dynamic Class Loading for C++ on Linux
Yes.
it sounds like your compiler is interpreting this line:
shape *my_shape = static_cast(mkr)();
as "cast 'mkr' to 'class shape *' " which is indeed wrong.
you want to cast 'mkr', which is of type pointer-to-function-returning-void*, to type pointer-to-function-returning-shape*, then call it.
Perhaps extracting the function pointer types out to typedefs would help you/the compiler clarify what is needed.
Or maybe just calling mkr(), then casting the returned pointer from void* to shape* would work equally well?
hth,
paulmg
Re: Dynamic Class Loading for C++ on Linux
#######################
Error while executing the above program of shape :::
In function `int main ()':
m.C:22: cannot dynamic_cast `mkr' (of type `void *') to type `class
shape *' (source is not a pointer to class)
Re: Dynamic Class Loading for C++ on Linux
I believe there is a missing
"pclose(dl);" statement.
No big deal.. but running this 'pluggin' framework,
in a loop causes a memory leak then.
Kind Regards,
Unk
--
http://www.triple-it.nl
Re: Dynamic Class Loading for C++ on Linux
I would also replace the command with
dlib = dlopen(name, RTLD_NOW);
by
dlib = dlopen(name, RTLD_NOW|RTLD_GLOBAL);
So symbols from one Shared Library Object file are avaible
to an other Shared Library Object file.
Unk
--
http://www.triple-it.nl/
Re: Dynamic Class Loading for C++ on Linux
I forget to mention that you should rename all the
maker() and proxy-class names.. to prevent name-clashes. (Otherwise you instantiate wrong classes)
Kind Regards,
Unk
--
http://www.triple-it.nl/