Shai Deshe
Shai Deshe

Reputation: 153

Writing dynamically loadable components in c++

I'm currently working on a program which should perform calculations on a home brewed data structure.

I want to build it in a way that it would be easy to add supported calculations (say, as source files which conform to a predetermined structure).

The problem is that I don't want to load all calculations in advance, because there might be a lot of them. The only mechanism I found which supports dynamic loading of functionality is dlopen, which expects .so files, so in this context, using dlopen means compiling a separate so file for every group of computations.

While I don't see any inherent problem with this design, my spider senses tell me I should verify with the all-knowing-web that it's not utterly stupid. If there are any other suggested ways to do so I'd be glad to hear.

Upvotes: 1

Views: 568

Answers (3)

John Källén
John Källén

Reputation: 7943

Seems like a good approach.

A good way to do this is to declare an abstract (pure) class in C++, say Calculator, with all the methods and accessors you need to perform a calculation. Then, have your separate dynamic libraries or .so files implement a global function Calculator * create_calculator() that creates an instance of a class that derives from Calculator. Finally, you'll have to devise a registration mechanism so that your main program can determine the name of the dynamic library to load, based on some kind of identifier like a string , enum, or uuid. This would typically be available as a easily editable configuration file.

void    *handle;
int     (*create_calculator)();

/* open the needed object file */
char    *libName = get_lib_name_from_config(identifier);
handle = dlopen(libName, RTLD_LOCAL | RTLD_LAZY);

/* find the address of create_calculator function */
create_calculator = (*(Calculator*)()) dlsym(handle, "create_calculator");
Calculator * calc = create_calculator();

This scheme can be made more flexible (and complex) by allowing the create_calculator method name to vary, at the cost of having to obtain that from the config file as well.

Upvotes: 1

thkala
thkala

Reputation: 86343

Using dlopen() is the most widely used way to load executable code dynamically in an application on POSIX-compatible operating systems. It allows using a modular architecture where optional or rarely used code is only loaded on-demand, which sounds pretty much like what you need.

I would certainly use this method - if after some time you find that the shared object compilation step is becoming a hurdle, you can build additional dynamically loaded modules to support e.g. an interpretted language such as Lua or Python. This would allow you to keep your existing codebase without losing in extensibility.

Upvotes: 1

Ernest Friedman-Hill
Ernest Friedman-Hill

Reputation: 81694

Opening shared libraries using dlopen() is certainly the first thing that comes to my mind; it's a fine plan.

Upvotes: 0

Related Questions