Subject: Dynamic loader / argument overloading example
From: Kevin Cameron x3251 (Kevin.Cameron@nsc.com)
Date: Tue Dec 17 2002 - 16:10:42 PST
The attached files demonstrate how the argument checking and dynamic 
loading work.
lib.cc contains too functions "foo" with different arguments and a 
locator which is
registered when test loads the library.
test.c creates contexts and calls the locator with different argument specs.
It works for g++ 2.95.2 on Solaris 2.8.
./test should give:
Locator for $root registered
Looking for int foo(int)
Looking for int foo(double)
Called (int)
foo(2)   = 6
Called (double)
foo(2.0) = 6
The code is cut down to a minimum to demonstrate routine selection on 
arguments,
but the calls are those in the proposal (except for svcInitLib which 
I'll add).
Regards,
Kev.
PS: For a different compiler, compile the code and do an "nm liblib.so" 
then sustitute
the strings given to the dlsym call in lib.cc
#include <stdio.h>
#include <varargs.h>
#include <dlfcn.h>
#include <link.h>
extern "C" {
#include "./sv2c.h"
}
static void *self; 
int foo(svcContext *cp,double arg) {
  fprintf(stderr,"Called (double)\n");
  return arg * 3;
}
int foo(svcContext *cp,int arg) {
  fprintf(stderr,"Called (int)\n");
  return arg * 3;
} 
static svcExtFunc myBinder( void *context,
                            char *modname,
                            char *inst_name,
                            char *rtn_name,
                            svcContext *p_context,...)
{
  svcExtFunc rtn_addr = 0;
  char *args[3];
  va_list    pv;
  va_start(pv);
  args[0] = va_arg(pv, char *);
  fprintf(stderr,"Looking for %s %s",args[0],rtn_name);      
  int a = 1;
  char *punc = "(";
  while (args[a] = va_arg(pv, char *)) {
    fprintf(stderr,"%s%s",punc,args[a++]); punc = ",";
  } 
  fprintf(stderr,")\n");      
  char *ep = 0;
  // You can put a lot of code here to calculate arbitrary
  // names - I'm cheating since I know we've only got two
  if (0 == strcmp(args[1],"int"))    ep = "foo__FP10svcContexti";
  if (0 == strcmp(args[1],"double")) ep = "foo__FP10svcContextd";
  
  svcExtFunc rp = 0;
  if (ep) {
    rp = (svcExtFunc) dlsym(RTLD_SELF,ep);
  }
  return rp;
}
extern "C" int svcInitLib(void *lib_handle)
{
  self = lib_handle;
  svcRegisterLocator(myBinder,0,"$root",0);
}
#include <stdio.h>
#include <dlfcn.h>
#include <link.h>
#include "sv2c.h"
svcContext foo_i,
           foo_d;
struct {
  svcLocater  func;
  void       *locator_context;
  char       *module_spec;
  int         capabilities;
} Locator_List;
int svcRegisterLocator(svcLocater locator,
                       void *locator_context,
                       char *module_spec,
                       int capabilities) {
  Locator_List.func = locator;
  fprintf(stderr,"Locator for %s registered\n",module_spec);
  
}
typedef void (*init_fn)();
typedef int (*fn_i)(svcContext *,int);
typedef int (*fn_r)(svcContext *,double);
main()
{
  void *lib  = dlopen("./liblib.so",RTLD_NOW),
       *init = dlsym(lib,"svcInitLib");
  if (init) {
    fn_i fi;
    fn_r fr;
    (*(init_fn)init)(lib);
    fi  = (fn_i)(*Locator_List.func)(0,  "$root",
                                         "$root",
                                         "foo",
                                         &foo_i,
                                         "int",
                                         "int",0
                                         );
    fr  = (fn_r)(*Locator_List.func)(0,  "$root",
                                         "$root",
                                         "foo",
                                         &foo_d,
                                         "int",
                                         "double",0
                                         );
    if (fi) {
      int i = (*fi)(&foo_i,2);
      fprintf(stderr,"foo(2)   = %d\n",i);
    }
    if (fr) {
      int i = (*fr)(&foo_d,2.0);
      fprintf(stderr,"foo(2.0) = %d\n",i);
    }
  }
}
This archive was generated by hypermail 2b28 : Tue Dec 17 2002 - 16:13:22 PST