(actually, I attended just to kill time, and most of the
subject matter being covered there was known to me :) )
and when learning perl modules, I came across AUTOLOAD
In brief, AUTOLOAD is like a default in a module, when one
tries to invoke a function which is not implemented in the
module, perl calls the function with name AUTOLOAD
passing the function name.
Having AUTOLOAD gives rise to interesting uses - atleast in
Perl. One can handle multiple calls in AUTOLOAD giving the
impression that there are lot of functions defined in the
library - especially useful when method names are like
get_a() get_b() get_c() etc.
I was trying to implement this in C, and its pretty
straight forward. All we need is a dynamic library and a
a default handler - which we shall call catch_all()
The only difference here would be, the responsibility
to call catch_all() will be with the invoker of the lib
(maybe this can be hidden behind neat APIs)
Lets create a library with a function and a catch_all
/* sotest.c */
#include
#include
void name1 ()
{
printf ("\n SOTEST: called %s\n", __FUNCTION__);
}
/* this is our AUTOLOAD method, which takes 1 param - name */
void catch_all (char *name)
{
/* If someone tried to call method hello() in this module */
if (0 == strcmp(name, "hello")) {
printf ("\n SOTEST: called hello()\n");
} else
printf ("\n SOTEST: %s, %s()\n", __FUNCTION__, name);
}
make lib: gcc -c -fPIC sotest.c; gcc -shared -fPIC -o libsotest.so sotest.o
Now for the invoker:
/* callso.c */
#include
#include
int main (int argc, char *argv[])
{
void *handle, (*fp)() = NULL, (*gfp)() = NULL;
char *fname = NULL;
if (argc <>\n", argv[0]);
exit (1);
}
fname = argv[1]; /* The function to be invoked in the lib */
handle = dlopen("./libsotest.so", RTLD_LOCAL | RTLD_LAZY);
fp = dlsym(handle, fname);
if (fp) {
fp(); /* If the named function exists, invoke it */
} else {
gfp = dlsym(handle, "catch_all");
gfp ? gfp(fname): 0; /* call the default handler if not */
}
return 0;
}
compile: gcc -L. callso.c -lsotest -ldl # Assume current dir, set LD_LIBRARY_PATH
Simple !. isn't it ? :)
No comments:
Post a Comment