From: twa@neuromancer.bellcore.com (Tom Ackenhusen)
Subject: Programmaticly controlled dynamic linking
Reply-To: twa@neuromancer.bellcore.com (Tom Ackenhusen)
Organization: Bell Communications Research
Date: Fri, 11 Dec 1992 20:42:08 GMT
Followup-To: comp.unix.programmer
Keywords: linker, sparc, question, comment

This is a detailed question concerning dynamic linking and programmatic
control of the dynamic linker.  Any help would be greatly appreciated.

I am trying to define wrapper functions for functions in a vendor-supplied
library.  I want to do this in such a way that I do not have to alter any
existing source code which calls the vendor library, I do not have to
duplicate all functions in the vendor library, and I still have access
(from my library routines) to all of the vendor library routines.  I need
to do this so that I can provide additional behavior for selected routines
in the vendor library without having to alter the installed base of
application code which uses the library (with the possible exception of
makefile changes and re-linking).  This requires my wrapper functions to
have identical names as the vendor functions that my functions enhance.
(I am actually trying to insert my code between application code and the
standard X Toolkit API.)

I think I may have an approach, but I'm not sure if it would work.  It
requires using a programmatic interface to the dynamic linker.  In my
case, since I am on Suns, I would be using the dlopen/dlsym/dlclose
routines.  This approach also requires that the vendor library be
available for dynamic loading (a shared library).  What I want to try is
to have my intermediate library code use dlopen to load the vendor library
and dlsym() to get handles to the vendor's functions to use to invoke the
functions.

(If it matters, my exact development environment is SunOS 4.1.1 on a
SPARCstation 2 using Sun's bundled compiler.  I am willing to change to
another compiler/linker/etc. if necessary.)

Does anyone know if this is possible?  Has anyone done it?  Is there a
good source of information on using the dlopen() routines and the linker?

The problems I can predict are:

1) Since my library won't duplicate all functions in the vendor library,
   the linker will have to load the vendor library symbol table at compile
   time.  This will result in duplicate symbol definitions.  How can I
   avoid this?  Can I designate some list of symbols to ignore duplicate
   definitions for?

2) Is it possible to call functions using the information returned
   from a dlsym() call?  How?

3) How can I insure that the run-time loading of the vendor library
   follows the same rules that it would if it were a normal dynamically-
   loaded library (using LD_LIBRARY_PATH and observing the shared object
   version number system, etc.)?  Are there available routines to do this,
   or will I need to duplicate this functionality with my code?

4) The vendor library must always be a shared object (or in a form
   that can be opened by dlopen()).  How restrictive is this
   constraint?

Also, if this approach worked, could the same approach be applied to most
UNIX environments which support dynamic linking?  I know the code wouldn't
be portable, but do most UNIX environments make this approach possible?

Please respond to me through e-mail.  I will summarize the information I
receive if there is interest.

Thanks.
-- 
Tom Ackenhusen			VITAL Computer contractor at
twa@ctt.bellcore.com		Bell Communications Research
[When I needed to do this, I wrote a little program that changed the names
of the symbols in the original shared library, then wrote wrappers under
the original name that called the old code using the changed name.  I had
applications I couldn't recompile, so I also needed to patch the apps to
add my new library to the list that they linked at startup time.  All of
the library data formats are well documented, so I did the whole thing in
an afternoon. -John]
-- 
Send compilers articles to compilers@iecc.cambridge.ma.us or
{ima | spdcc | world}!iecc!compilers.  Meta-mail to compilers-request.