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