Dynamic loading

Dynamic loading

Post by Jason B. Johnso » Sun, 12 Dec 1999 04:00:00



I am not sure if this is the proper place for this message, but at least
maybe someone can point me in the proper direction.

I am in the process of writing a Database Interface system in C++.  It
is based (to a certain extent) on the perl Database interface system of
the same name (DBI).  The spec is: there is a DBI factory class which
creates a Database Driver object (DBDs) and returns a pointer to it, to
the end-user application.  All DBDs are derived from an abstract DBD
class, which defines the user interface.  A DBD will need to be written
for every database back end that will be supported (e.g.  "class
Oracle_DBD : public DBD", etc.).  The DBI code will be written and
compiled well before the first real DBD is written, and will not need a
recompile.  Therefore, the actual Database driver code will have to be
loaded run-time.  Here is an example DBI factory method:

DBD *DBI::connect(char *db_string, char *user, char *password)
{
     void *handle;

    // parse db_string and determine which DBD is required

    // find the location of the DBD shared object file

    handle = dlopen(dbd_so_file, flags);

    typedef DBD *(*fctp)(char *, char *, char*);
    fctp conn;

    string connect_func = dbd_name + "_connect";

    conn = (fctp)dlsym(handle, connect_func.c_str());

    DBD *dbh = (*conn)(db_string, user, password);

    // any extra checking

    return dbh;

Quote:}

This part works correctly.  The problem is when the application tries to
call a virtual method from the DBD pointer.  Example:

int main()
{
    DBI dbi;

    DBD *dbh = dbi.connect("DBD:Oracle:localhost", "me",
"mePassword");    // works just fine

    dbh->prepare("select * from table");        // core dump at this
point

   // .....

The abstract class DBD would be something like:

class DBD {
public:
    // ....
    virtual void prepare(char *sql) = 0;
    virtual ~DBD() { }
    // ...

Quote:};

I would have expected the virtual function to have resolved correctly in
the call  "dbh->prepare( /* ... */ )" because of the virtual mechanisms
(although, I do not know how that is implemented in egcs).  Apparently
this is not the case.

I suppose I could simply write an inline DBD "wrapper" class that
resolves *all* supported functions and then gets returned from the DBI
factory method.  For example:

class DBD_wrapper : public DBD {
    void (*prep)(char *);
    // ...
public:
    DBD_wrapper( /* ... */) { /* set up all function pointers */ }
    // ...
    void prepare(char *sql) { return (*prep)(*sql); }
// defined inside class, therefore implicitly inlined
    // ...

Quote:};

This would be one solution, but it would change the way the DBDs would
have to be written.  That is, notice that the definitions for the user
interface functions (prepare for example) are not methods of a class,
but functions.  This implies that there is nothing derived from the base
class DBD except the wrapper class.  As I see it (based on this
observation) the "wrapper" class design is not nearly as elegant,
maintainable, etc. as the design involving the class heir achy.  But
alas, it is better having a working hack then a beautiful theory that
does not work.

I am hoping that someone might have information (via documentation,
pointing me to the correct news group, or just knowledge "off the top of
there head") that would help me get the heir achy design to work.

I would greatly appreciate it if any responses could be sent (or carbon

on business this week.

Thanks in advance,

Jason

 
 
 

1. dynamic loading: linker bug w.r.t. --export-dynamic ?

Hi

I have file1.c that defines function fn. I also have file2.c that _declares_
function fn (with the same signature).

I use file1.c to make an exectuable file1 :

gcc -rdynamic -c file1.c
gcc -rdynamic --export-dynamic -o file1 file1.o -ldl )

And I use file2.c to make a shared library ./libfile2.so :

gcc -rdynamic -c file2.c
gcc -shared -rdynamic --export-dynamic -o libfile2.so file2.o

file1 dynamically loads libfile2.so at run-time. This loading fails at
run-time if and only if file2 _uses_ the aforementioned function fn :

./libfile2.so: undefined symbol: fn

I'm a very puzzled by this, since ld manual says, in part:

"--export-dynamic
    When  creating a dynamically linked executable, add all symbols
    to the dynamic symbol table.  The dynamic symbol table is the
    set of symbols which are visible from dynamic objects at run time."

Is this option being ignored? (I use some compiler and linker options
redundantly just in case)

My system is Debian 3.0; dl library is part of libc6 2.2.5;
I got the same results with GCC 3.2.2 and GCC 2.95.4

Thank you
Oleg

2. password policy and yppasswd

3. dynamic loading vs. dynamic linking

4. PROBLEM : 10/100MB Ethernet MC Adapter

5. Does Perl5.001 dynamic-load in Linux? How?

6. Sync cards in PC with linux - Question

7. Dynamic Loading Of Libraries and access to ld.so

8. Unix workstation as personal computer?

9. Q's re: shared libs, dynamic loading

10. Perls dynamic loading fails for Linux.

11. Q: dynamic loading of C++ code to Python --- how to call global constructors?

12. Dynamic loading of modules in AIX

13. problem with dynamic loading of shared library