Subject: Dynamic loader / argument overloading example2 + proposal update
From: Kevin Cameron x3251 (Kevin.Cameron@nsc.com)
Date: Wed Dec 18 2002 - 10:19:37 PST
I added a bit more code to the example to demonstrate how the linker phase
can set up user-context data for the actual calls.
In lib.cc where the right routine is selected there are assignments to the
"p_context->user_context" field. That field is re-used in the subsequent
calls either "foo" - the int version has a context value 3, and the double
version uses 3.6. The output from test is then:
Locator for $root registered
Looking for int foo(int)
Looking for int foo(double)
Called (int)
foo(2) = 6
Called (double)
foo(2.0) = 7
I also added in the instance handle passing for completeness (although it
does nothing in this example).
If there is any other functionality folks would like to see demonstrated
I can
easily add it.
I also attached an updated version of the proposal including the svcInitLib
extension (for initialazing DLLs).
Regards,
Kev.
#include <stdio.h>
#include <varargs.h>
#include <dlfcn.h>
#include <link.h>
extern "C" {
#include "./sv2c.h"
}
static void *self;
int foo(handle ip, svcContext *cp,double arg) {
fprintf(stderr,"Called (double)\n");
return arg * cp->user_context.dbl;
}
int foo(handle ip, svcContext *cp,int arg) {
fprintf(stderr,"Called (int)\n");
return arg * cp->user_context.data[0];
}
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__FPvP10svcContexti";
p_context->user_context.data[0] = 3;
}
if (0 == strcmp(args[1],"double")) {
ep = "foo__FPvP10svcContextd";
p_context->user_context.dbl = 3.6;
}
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)(handle,svcContext *,int);
typedef int (*fn_r)(handle,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)(0,&foo_i,2);
fprintf(stderr,"foo(2) = %d\n",i);
}
if (fr) {
int i = (*fr)(0,&foo_d,2.0);
fprintf(stderr,"foo(2.0) = %d\n",i);
}
}
}
This archive was generated by hypermail 2b28 : Wed Dec 18 2002 - 10:22:17 PST