Dynamic Class Loading for C++ on Linux

May 1st, 2000 by James Norton in

A technique for developers that will provide them with much flexibility in design.
Your rating: None Average: 4.6 (45 votes)

Linux has much to offer as a development platform: a robust operating environment with tested tools. Linux also boasts implementations of just about every programming language available. I think it is safe to say, however, that among compiled languages, C is the language of choice for most Linux developers. Consequently, other languages such as C++ seem to be somewhat neglected in most discussions of Linux development.

The dynamic class loading technique provides developers with a great deal of flexibility in their designs. Dynamic class loading is a means of providing extensibility without sacrificing robustness.

In this article, we will design a simple application that defines a single class, a shape class we wish to use in a drawing package. As we shall see, dynamic class loading allows us to provide a smooth extension path through which users of the application can add new types of shapes without needing to modify the original application code.

Polymorphism

The basic idea behind dynamic class loading is the concept of polymorphism. Anyone familiar with C++ should be familiar with this concept, so I will discuss it here only briefly. In short, polymorphism is the ability of an object belonging to a derived class to act as an object belonging to the base class. This is the familiar “is a” relationship of OOP (object-oriented programming) parlance. For example, in the following code snippet, circle is a class derived from the base class shape (see Listing 1), so the object my_circle can act as a shape object, invoking the shape member function draw.

Listing 1

class shape { public:
   void draw();
};
class circle : public shape { };
int main(int argc, char **argv){
   circle my_circle;
   my_circle.draw();
}

While this has all the usual advantages, e.g., code reuse, the real power of polymorphism comes into play when draw is declared to be virtual or pure virtual, as follows:

class shape{ public:
   virtual void draw()=0;
};
class circle : public shape { public:
   void draw();
}
Here, circle has declared its own draw function, which can define behavior appropriate for a circle. Similarly, we could define other classes derived from shape, which provide their own versions of draw. Now, because all the classes implement the shape interface, we can create collections of objects that can provide different behavior invoked in a consistent manner (calling the draw member function). An example of this is shown here.
shape *shape_list[3];   // the array that will
                            // pointer to our shape objects
shape[0] = new circle;  // three types of shapes
shape[1] = new square;  // we have defined
shape[2] = new triangle;
for(int i = 0; i < 3; i++){
   shape_list[i].draw();
}
When we invoke the draw function for each object on the list, we do not need to know anything about each object; C++ handles the details of invoking the correct version of draw. This is a very powerful technique, allowing us to provide extensibility in our designs. Now we can add new classes derived from shape to provide whatever behavior we desire. The key here is that we have separated the interface (the prototype for shape) from the implementation.

While this technique is very powerful, it does suffer from a drawback in that we must recompile (or at least relink) our code when we add new derived classes. It would be more convenient if we could simply load in new classes at runtime. Then, anyone using our code libraries could provide new shape classes (with new draw functions) without even needing our original source code. The good news, and the subject of this article, is that we can.

dlopen and Dynamic Class Loading

While C++ has no direct mechanism under Linux for loading in classes at runtime, there is a direct mechanism for loading C libraries at runtime: the dl functions dlopen, dlsym, dlerror and dlclose. These functions provide access to the dynamic linker ld. A complete description of these functions is provided in the appropriate man page, so they are presented here only briefly.

The prototypes for the functions are as follows:

void *dlopen(const char
void *dlsym(void *handle, char *symbol);
const char *dlerror();
int dlclose(void *handle);

The dlopen function opens the file given in filename so that the symbols in the file can be accessed via the dlsym function. flag can take one of two values: RTLD_LAZY or RTLD_NOW. If flag is set to RTLD_LAZY, dlopen returns without attempting to resolve any symbols. If flag is set to RTLD_NOW, dlopen attempts to resolve any undefined symbols in the file. Failure to resolve a symbol causes the call to fail, returning a NULL. dlerror can be used to provide an error message explaining the failure. The dlsym function is used to obtain a pointer to the functions (or other symbols) provided by the library. handle is the pointer to the thing being referenced, and symbol is the actual string name of the item referenced, as it is stored in the file.

Given that we can use these functions to access functions in a C library, how do we use them to access classes in a C++ library? There are several problems to overcome. One is that we must be able to locate the symbols we need in the library. This is trickier than it might seem because of the difference between the way symbols are stored in C and C++ files. Secondly, how can we create objects belonging to the classes we load? Finally, how can we access those objects in a useful manner? I will answer these three questions in reverse.

Since we do not have the prototypes for the classes we load dynamically, how can we access them in our code? The answer to this lies in the description of polymorphism in the preceding section. We access the functionality of the new classes through the common interface provided by their base class. Following the examples above, any new shape classes would provide a draw function that would allow an object of that class to render itself.

Fine; we can use pointers to the base class to access objects from the derived classes. How do we create the objects in the first place? We don't know anything about the classes that might be loaded, other than the fact that they conform to the shape interface. For instance, suppose we dynamically load a library that provides a class called hexapod. We can't write

shape *my_shape = new hexapod;

if we don't know the class name ahead of time.

The solution is that our main program doesn't create the objects, at least not directly. The same library that provides the class derived from shape must provide a way to create objects of the new class. This could be done using a factory class, as in the factory design pattern (see Resources) or more directly using a single function. To keep things simple, we will use a single function here. The prototype for this function is the same for all shape types:

shape *maker();

maker takes no arguments and returns a pointer to the constructed object. For our hexapod class, maker might look like this:

shape *maker(){
   return new hexapod;
}
It is perfectly legal for us to use new to create the object, since maker is defined in the same file as hexapod.

Now, when we use dlopen to load a library, we can use dlsym to obtain a pointer to the maker function for that class. We can then use this pointer to construct objects of the class. For example, suppose we want to dynamically link a library called libnewshapes.so which provides the hexapod class. We proceed as follows:

void *hndl = dlopen("libnewshapes.so", RTLD_NOW);
if(hndl == NULL){
   cerr << dlerror() << endl;
   exit(-1);
}
void *mkr = dlsym(hndl, "maker");

The pointer to maker must be of type void *, since that is the type returned by dlsym. Now we can create objects of the hexapod class by invoking mkr:

shape *my_shape = static_cast<shape *()>(mkr)();
We are required to cast mkr to a pointer to a function returning shape * when we invoke it.

Some readers may see a problem with the code as written thus far: the dlsym call is likely to fail because it cannot resolve "maker". The problem is that C++ function names are mangled to support function overloading, so the maker function may have a different name in the library. We could figure out the mangling scheme and search for the mangled symbol instead, but fortunately there is a much simpler solution. We need only tell the compiler to use C-style linkage using the extern "C" qualifier, as shown in Listing 2.

Listing 2

Autoregistration

Loading the maker functions into an array associates a position in the array with each maker. While this may be useful in some cases, we can obtain more flexibility using an associative array to hold the makers. The Standard Template Library (STL) map class works well for this, as we can then assign key values to the makers and access them via these values. For example, we may desire to assign string names to each class and use these names to invoke the appropriate maker. In this case, we can create a map such as this:

typedef shape *maker_ptr();
 map <string, maker_ptr> factory;

Now when we want to create a particular shape, we can invoke the proper maker using the shape name:

shape *my_shape = factory[
We can extend this technique to make it even more flexible. Rather than loading the class makers in and explicitly assigning a key value to them, why not let the class designers do the work for us? Using a little bit of ingenuity, we can have the makers register themselves with the factory automatically, using whatever key value the class designer chooses. (There are a couple of warnings here. The key must be of the same type as all the other keys, and the key value must be unique.)

One way to accomplish this would be to include a function in each shape library that registers the maker for us, and then call this function every time we open a shape library. (According to the dlopen man page, if your library exports a function called _init, this function will be executed when the library is opened. This may seem to be the ideal place to register our maker, but currently the mechanism is broken on Linux systems. The problem is a conflict with a standard linker object file, crt.o, which exports a function called _init.) As long as we are consistent with the name of this function, the mechanism works well. I prefer to forego that approach in favor of one that will register the maker simply by opening the library. This approach is known as “self-registering objects” and was introduced by Jim Beveridge (see Resources).

We can create a proxy class used solely to register our maker. The registration occurs in the constructor for the class, so we need to create only one instance of the proxy class to register the maker. The prototype for the class is as follows:

class proxy {
public:
   proxy(){
      factory["shape name"] = maker;
   }
};

Here, we assume factory is a global map exported by the main program. Using gcc/egcs, we would be required to link with the rdynamic option to force the main program to export its symbols to the libraries loaded with dlopen.

Next, we declare one instance of the proxy:

proxy p;

Now when we open the library, we pass the RTLD_NOW flag to dlopen, causing p to be instantiated, thus registering our maker. If we want to create a circle, we invoke the circle maker like so:

shape *my_circle = factory["circle"];
The autoregistration process is powerful because it allows us to design the main program without having explicit knowledge of the classes we will support. For instance, after the main program dynamically loads any shape libraries, it could create a shape selection menu using all the keys registered in the factory. Now the user can select “circle” from a menu list, and the program will associate that selection with the proper maker. The main program does not need any information about the circle class as long as the class supports the shape API and its maker is properly defined.

Listing 3

Listings 1 through 5 pull together the concepts presented thus far. The shape class defined in Listing 1 is the base class for all shapes. Listings 2 and 3 are the source code for dynamically loadable libraries that provide circle and square shapes, respectively.

Listing 4

Listing 4 is the main program that is extensible through dynamically loaded libraries. It scans the current directory for any .so files (libraries) and opens them. The libraries then register their makers with the global factory provided by the main program. The program then dynamically constructs a menu for the user with the shape names registered by the libraries. Using the menu, the user can construct shapes, draw the shapes constructed, or exit the program. Listing 5 is the makefile used to build the project.

Listing 5

Real-World Examples

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);
Conclusion

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.

Resources

James Norton spent most of his adult life avoiding real life by hiding out in school, first at Florida State University and then at Tulane University. The good life ended when he was awarded a Ph.D. in Electrical Engineering through what could only have been some sort of clerical error. He currently does research and systems development for Newsreal, Inc. He can be reached by e-mail at jnorton4@home.com.

__________________________


Special Magazine Offer -- Free Gift with Subscription
Receive a free digital copy of Linux Journal's System Administration Special Edition as well as instant online access to current and past issues. CLICK HERE for offer

Linux Journal: delivering readers the advice and inspiration they need to get the most out of their Linux systems since 1994.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Alejo's picture

You mean shape *my_circle

On October 27th, 2009 Alejo (not verified) says:

You mean
shape *my_circle = factory["circle"]();
rather than
shape *my_circle = factory["circle"];

Nice article. :-)

L S Srinivas Kothuri's picture

Cpp

On April 17th, 2009 L S Srinivas Kothuri (not verified) says:

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.

Greg Kogut's picture

Very useful

On December 30th, 2008 Greg Kogut (not verified) says:

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

John Gruenenfelder's picture

Thank you for the article

On August 22nd, 2008 John Gruenenfelder (not verified) says:

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.

Anonymous's picture

Nice Article

On April 8th, 2007 Anonymous (not verified) says:

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.

Anonymous's picture

It's all so wrong

On September 23rd, 2006 Anonymous (not verified) says:

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

Anonymous's picture

And I feel dumber for having

On August 27th, 2007 Anonymous (not verified) says:

And I feel dumber for having read your comment. :-(

Anonymous's picture

very constructive comment!

On March 20th, 2007 Anonymous (not verified) says:

probably from a .net zealot!
I actually like this article if only for the learning experience.

bensch's picture

usage with Automake

On February 20th, 2006 bensch (not verified) says:

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

Anonymous's picture

Anybody could provide a

On April 11th, 2006 Anonymous (not verified) says:

Anybody could provide a working Makefile?, I can not understand how such a nice article can have this Makefile...

Anonymous's picture

Makefile: You have to type

On May 28th, 2008 Anonymous (not verified) says:

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

Chetan Risbud's picture

management of vtable

On November 4th, 2005 Chetan Risbud (not verified) says:

Hi,

I just want to know the how does this manages the vtable after laoding the class dynamically ?

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On September 1st, 2004 Anonymous says:

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)

Anonymous's picture

Cross-platform loading of libraries.

On October 20th, 2003 Anonymous says:

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++).

Anonymous's picture

Re: Cross-platform loading of libraries.

On November 24th, 2003 Anonymous says:

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
}

Anonymous's picture

can you create an object (of

On December 7th, 2005 Anonymous (not verified) says:

can you create an object (of a class in the dll) using GetProcAddress? pls help...

Anonymous's picture

Re: Cross-platform loading of libraries.

On November 5th, 2003 Anonymous says:

If you're writing a Qt application, you have the QLibrary class that OS independent resolves symbols from .so's resp. .dll's.

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On April 3rd, 2003 Anonymous says:

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;

}

};

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On February 26th, 2003 Anonymous says:

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

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On June 23rd, 2003 Anonymous says:

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

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On June 23rd, 2003 Anonymous says:

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

Anonymous's picture

You can use reinterpret_cast

On April 24th, 2007 Anonymous (not verified) says:

You can use reinterpret_cast instead of static_cast. This works for me.

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On November 24th, 2002 Anonymous says:

XPLC does all of this, faster, better, simpler, safer.

http://xplc.sourceforge.net/

Anonymous's picture

xplc is 0.3.0 Alpha

On August 14th, 2003 Anonymous says:

I presume that's why more stable is missing on your list of properties...

Anonymous's picture

Re: xplc is 0.3.0 Alpha

On October 20th, 2003 Anonymous says:

Well, this is just some dlopen() sample code in an article, it's not like it's exactly a solid framework either...

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On March 14th, 2003 Anonymous says:

bull***** it does.. lol

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On September 30th, 2002 Anonymous says:

Is there any particular reason why deleting objects is omitted?

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On September 1st, 2002 Anonymous says:

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

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On December 18th, 2001 Anonymous says:

That factory is nice idea but there are some problems with it:

  • It can be slow.
  • It requires extern "C" functions _init() and _fini() in the library. And in dynamic loader there is a serious bug: if you use any of these functions then global static objects are not constructed (i.e. their constructor is not called) so they are in undefined state.
Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On February 12th, 2004 Anonymous says:

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.

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On August 9th, 2002 Anonymous says:

#######################

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 ????

TeacherDon's picture

I found out what the problem

On March 21st, 2005 TeacherDon (not verified) says:

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)();

Anonymous's picture

A minor correction:

On April 16th, 2007 Anonymous (not verified) says:

A minor correction:

shape * my_shape = function_cast(mkr)();

Anonymous's picture

A correction of my

On April 16th, 2007 Anonymous (not verified) says:

A correction of my correction:
shape * my_shape = function_cast(mkr)();

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On September 23rd, 2004 Anonymous says:

Hi,

You can try this way :

shape *(*mkr)()= (shape*(*)())dlsym(dlib, "maker");
shape *my_shape = (*mkr)();
my_shape->draw();

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On August 13th, 2002 Anonymous says:

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!

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On August 13th, 2002 Anonymous says:

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

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On August 9th, 2002 Anonymous says:

#######################

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)

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On July 23rd, 2002 Anonymous says:

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

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On September 19th, 2002 Anonymous says:

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/

Anonymous's picture

Re: Dynamic Class Loading for C++ on Linux

On September 19th, 2002 Anonymous says:

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/

Post new comment

Please note that comments may not appear immediately, so there is no need to repost your comment.
The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <pre> <ul> <ol> <li> <dl> <dt> <dd> <i> <b>
  • Lines and paragraphs break automatically.

More information about formatting options

Newsletter

Each week Linux Journal editors will tell you what's hot in the world of Linux. You will receive late breaking news, technical tips and tricks, and links to in-depth stories featured on www.linuxjournal.com.
Sign up for our Email Newsletter

Tech Tip Videos

From the Magazine

December 2009, #188

If last month's Infrastrucuture issue was too "big" for you then try on this month's Embedded issue. Find out how to use Player for programming mobile robots, build a humidity controller for your root cellar, find out how to reduce the boot time of your embedded system, and if you're new to embedded systems find out the basics that go into one. You can also read about the Beagle Board, the Mesh Potato and a spate of other interestingly named items. And along with our regular columns don't miss our new monthly column: Economy Size Geek.







Read this issue