Dynamically Loaded Functions

Dynamically Loaded Functions

Post by David Hilse » Tue, 21 May 2002 21:56:24




Quote:> A little challenge for you today ...

> I've 'inherited' an application that is made up of a core
> framework plus a (large) number of externally-written
> "transactions" that are called from the core.  As it stands,
> the application is *recompiled* every time a new transaction
> is added (calls are made through a "switch" statement built
> based on the included transcations).  I'd like to move away
> from this.

> Each "transaction" is a call to a 'C' function with one of two
> sets of arguments (which depends on the transaction's source
> language for some reason - /still/ not sure why, but it's early
> days yet).

> Given that each "transaction" function is in its own object file
> (currently a ('C') .o or COBOL .int ), can I dynamically load
> an object file and call a named function within it?  Just to
> make matters even more tempting, each transaction is
> identified by a number (unique but, sadly, non-sequential) .
> Can I generalise this process still further and use, say, an
> array of function pointers to make this loading process
> totally generic?  My aim, simply put, is to allow new
> transactions to be added without /any/ change to the core framework
> source (I fully expect to have to re-Link it,
> though).

> I'm currently running Solaris 2.6 but moving to Solaris 8
> soon, so future-proofed suggestions much appreciated.

Since the unique integers are non-sequential, but unique, I'd suggest a
std::map.  For example:

// Header
typedef /*whatever*/ FuncPtr;
bool AddFunction(int id, FuncPtr func);

// implementation
#include "Header.h"
#include <map>
#include <utility>

namespace {
    std::map<int,FuncPtr> table;

Quote:}

bool AddFunction(int id, FuncPtr func) {
    return table.insert(std::make_pair(id,func)).second;

Quote:}

That should allow you to eliminate the switch statement that is causing the
recompile with minimal fuss, because it becomes a simple call to
std::map::find.  If you want, you can have two tables, one for each set of
arguments, or you can try to write some sort of wrapper for the different
functions so they may be inserted into the same table and called via a
common interface.

--
David Hilsee