function name to function address translation?

D

DOA

Help! I've been doing C language development for a long time, but this
problem has me stumped.

I would like the user to be able to enter the name of a function that
has been linked into the application they are currently running, and
have the application call the function they have requested.

Example code:

char fn_name[80];
int (*p_fn)(int,int,int *);
int res1,res2;

printf("Function name? ");
scanf("%s",fn_name);

p_fn = translate_function_name_to_function_address(fn_name);
if (p_fn)
res2 = (*p_fn)(5,20,&res1);
else
printf("ERROR - requested function not found\n");

Question: is a function to do the name-to-address translation
available in most (or any) C libraries and associated development
environments? If not, how would you do it?

Thanks in advance for any hints!
Steve

P.S. Ideally, I wouldn't have to do any custom programming to support
this functionality (e.g. build and search a function name to function
address translation table myself).
 
B

Ben Pfaff

I would like the user to be able to enter the name of a function that
has been linked into the application they are currently running, and
have the application call the function they have requested.

This is a FAQ.

20.6: If I have a char * variable pointing to the name of a function,
how can I call that function?

A: The most straightforward thing to do is to maintain a
correspondence table of names and function pointers:

int func(), anotherfunc();

struct { char *name; int (*funcptr)(); } symtab[] = {
"func", func,
"anotherfunc", anotherfunc,
};

Then, search the table for the name, and call via the associated
function pointer. See also questions 2.15, 18.14, and 19.36.

References: PCS Sec. 11 p. 168.
 
G

Gustavo G. Rondina

From the book Advanced Linux Programming:

--open quote--
2.3.6 Dynamic Loading and Unloading

Sometimes you might want to load some code at run time without
explicitly linking in that code. For example, consider an application
that supports "plug-ins" modules, such as a Web browser...

This Functionality is avaliable under Linux by using the dlopen()
function. You could open a shared library named libtest.so by calling
dlopen() like this:

dlopne("libtest.so", RTLD_LAZY)

(The second parameter is a flag that indicates how to bind symbols in
the shared library. You can consult the man pages for dlopen if you
want more information, but RTLD_LAZY is usually the setting that you
want.) Yo use dynamic loading functions, include the <dlfcn.h> header
file and link with the -ldl option to pick up the libdl library.

The return value from this function is a void * that is used as a
handle for the shared library. You can pass this value to the dlsym()
function to obtain the address of a function that has been loaded with
the shared library. For example, if libtest.so defines a function
named my_function(), you could call it like this:

void* handle = dlopen("libtest.so", RTLD_LAZY);
void (*test)() = dlsym(handle, "my_function");
(*test)();
dlclose(handle);

The dlsym() system call can also be used to obtain a pointer to a
static variable in the shared library.

Both dlopen() and dlsym() return NULL if they do not succeed. In that
event you can call dlerror() (with no parameters) to obtain a
human-readable error message describing the problem.

The dlclose() function unloads the shared library. Technically,
dlopen() actually loads the library only if it is not already
loaded. If the library has already been loaded, dlopen() simply
increments the library reference count. Similarly, dlclose()
decrements the reference count and then unloads the library only if
the reference count has reached zero.
--close quote--

Maybe that might help.


Regards
 
S

Stefan Ram

/* [email protected] (DOA) said:
Question: is a function to do the name-to-address translation
available in most (or any) C libraries and associated development
environments? If not, how would you do it?

The following code was written to show how one might avoid to
have to repeat the names of the functions, i.e., avoid to have
to maintain a separate list of function names in the source
code. */

/*
< filename = [stringcall.c]
encoding = [ANSI_X3.4-1968]
notation = [ISO/IEC 9899:1999 (E)]
author = [Stefan Ram] > */

#include <stdio.h> /* puts */
#include <string.h> /* strcmp */

#define F(r,n,b) r n b
#define FUNCTIONS \
F( void, beta, (){ puts( "Bravo" ); } )\
F( void, zeta, (){ puts( "Zulu" ); } )\
/**/
FUNCTIONS
#undef F

#define F(r,n,b) n,
void( * const function[] )() ={ FUNCTIONS };
#undef F

#define F(r,n,b) #n,
char const * const name[] ={ FUNCTIONS };
#undef F

int const top = sizeof name / sizeof 0[ name ];

void call( char const * const n )
{ int i; for( i = 0; i < top; ++i )
{ if( !strcmp( n, i[ name ]))i[ function ](); }}

int main( void ){ call( "beta" ); call( "zeta" ); }

/* stdout will be:

Bravo
Zulu

*/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,991
Messages
2,570,212
Members
46,800
Latest member
Tobi1987

Latest Threads

Top