Solved

Function Pointer in C

Posted on 1998-09-02
16
241 Views
Last Modified: 2012-05-04
In one of my prject, I want to convert String/Char * to a function pointer. String/Char * contains the name of the function decided at runtime. How to write a code so that after type-casting the char * to function pointer, I can execute the function by just calling it?

Further, I want to add RunTime to the list of functions without modifying the code. The only thing, I know, is the string which I am passing, represents the name of the function. Function does exist by that NAME. At runtime, I can select any function for calculation. This code must work across different platforms and OS
0
Comment
Question by:prafulla
  • 5
  • 3
  • 2
  • +5
16 Comments
 
LVL 5

Expert Comment

by:ecw
ID: 1252457
You can't do this by casting.  A quick in easy way, is to create a lookup table between function name and function.  Then when your code must call a function by name, search the table for the name, and if found call the associated function.  eg.

#include <string.h>

/* typedef'ing saves hassle later */
typedef char *(*fptr)();

struct {
  char *name;
  fptr func;
} f_map[] = {
  { "strcat",  strcat },
  { "strcpy", strcpy },
  { 0, 0 }
} ;

fptr f_lookup(char *name)
{
int i;
  for (i = 0; f_map[i].name; ++i) {
    if (! strcmp(f_map[i].name, name)) return f_map[i].func;
  }
  return 0;
}

/* and to use it */
void somefunc(char *s1, char *s2)
{
fptr func = f_lookup("strcat");
  if (func) func(s1, s2);
}

0
 
LVL 3

Expert Comment

by:danny_pav
ID: 1252458
you might think about using an index instead of the string and using the above solution
0
 
LVL 2

Expert Comment

by:duneram
ID: 1252459
and if you want to get a little fancier, take the string with the above method, and generate a hash (index) and then use that.....

If you are in windows, and using the SDK  you can use the GetProcAddress() api to retrieve a function by text name or by export ordinal number.
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
LVL 3

Expert Comment

by:elfie
ID: 1252460
If you are working on Unix machine, some standard routine exist.

try doing a man shl_load (HPUX) or man dlload (Sun). There you will find information on how to execute routine that are present in 'some' libraries (or running program)
0
 

Author Comment

by:prafulla
ID: 1252461
Edited text of question
0
 
LVL 11

Expert Comment

by:alexo
ID: 1252462
You can call functions by name in interpreted languages.  C is compiled.
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1252463
There's no portable way to do this.  
You can use UNIX and Windows functions to do a platform specific way.  You can even use a double indirection and a bit of clever pre-processor magic to keep the platform specific stuff in one place.
That's the best real answer you'll get.


For a "fun" answer, I have realized in C++ you can almost do this

1. Setup a singleton class which stores a map of pointers to objects and their names.

2. Setup an abstract base class.  Base functionality of this class is to add itself into the map.

3. Each function then goes in a singleton derived class of 2

4. Use the pre-processor to hide most (I don't think all) of the horrible syntax anamolies, ' and ## pre-processor operators will prove useful here.

Of course, I'd never do this in practice...having said this I don't think this will be totally clean.
0
 
LVL 3

Expert Comment

by:elfie
ID: 1252464
I agee with Answer2000.

There is no portable way of doing this. You can define your own "load3 routine. Inside this routine you will have some pre-compiler directives so you can write code for each individual OS.

Each OS has its specific calls (see above eg shlload and dlload)
This is needed because there are different formats of libraries and executables. (e.g. ELF format)

0
 
LVL 10

Accepted Solution

by:
rbr earned 60 total points
ID: 1252465
Sorry there will be no way to do this directly. You have to write a parser which is able to interpreted the string (=function, formula) you want to execute.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1252466
I suggest you "reopen" the question because the currently pending answer does not help you much.

>> This code must work across different platforms and OS
The only portable way to accomplish that is using a pre-compiled mapping between a string and a function pointer.  It is easier in C++ because you can use the STL for maps, etc., but it is possible in C too.  You could implement a hash table for best speed but a binary search is a good compromise too if the number of functions is not too large (say, a couple of hundreds?).

Here's a sample program that handles 3 trig functions:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

typedef double (*PFUNC)(double);

typedef struct {
    char* name;
    PFUNC pFunc;
} COUPLE;

int Compare(const void* pStr, const void* pCouple);

COUPLE map[] = { /* Must be sorted by string! */
            { "cos", cos },
            { "sin", sin },
            { "tan", tan }
};

void main()
{
    const double arg = 0.5;

    for(;;)
    {
        char name[64];
        COUPLE* result;

        printf("> ");
        gets(name);
        result = (COUPLE*)bsearch(name, map, sizeof(map) / sizeof(*map), sizeof(*map), Compare);
        if (!result)
            break;
        printf("%s(%f) = %f\n", name, arg, result->pFunc(arg));
    }
}

int Compare(const void* pStr, const void* pCouple)
{
    return strcmp((char*)pStr, ((COUPLE*)pCouple)->name);
}

It can be generalized to handle more than one argument by including a "number of arguments" field in the structure and switching on it.  The PFUNC type will have to be declared as taking an unknown number of arguments (empty parentheses) and some casting may be involved.
0
 

Author Comment

by:prafulla
ID: 1252467
I want it to be done in C as s/w on which I am working supports C integration. And we have couple of our previous C code available for current projects core items. So I don't want to rewrite them.
Thank you for the response. If anybody finds the answer. Kindly update the answer-list.

Regards!
0
 
LVL 11

Expert Comment

by:alexo
ID: 1252468
prafulla, what's wrong with my suggestion?
0
 
LVL 5

Expert Comment

by:ecw
ID: 1252469
Or indeed my suggestion, simple but does the job.  I think embedding a parser (in fact an interpreter) to evaluate a function is far more complex than a table lookup, and will probably rely on table lookups (switch statements anyone?) to do its job.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1252470
ecw, a simple loop (like you suggested) is quivalent to a linear search and may have to compare all the strings (worst case).  A binary search (like I suggested) needs log(N) compares and a hash table (duneram's suggestion) is the most efficient but needs the most programming effort.  Actually, the principle is the same: a mapping between a string and a pointer to function.  I have no idea why prafulla accepted a patently wrong answer.
0
 
LVL 5

Expert Comment

by:ecw
ID: 1252471
Why bother with a binary search or hash lookup for a small data set?  Granted we don't know the number of names to lookup, but I doubt very much whether it'll approach the pint where search times, even liner search times, become and issue.  Both our examples use a data set size (2 or 3 elements) that will be faster to search linearly than using bsearch.  Note, I'm not criticising your solution, for large data sets, it'll certainly be faster, just as hashing will be faster still, but as an illustration, I think it's adequate.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1252472
>> Why bother with a binary search or hash lookup for a small data set?
Because, as you mentioned yourself, we don't know the number of names to lookup, nor the length of the strings.  I also happen to personally dislike linear searches, and if you compare our solutions you'll see that the "bother" for a binary search is virtually nil.  I agree that a hash table is an overkill.
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
distributed computing in Python 4 123
How to translate this 2-line while loop into C from Perl? 8 95
Why is compiler in oracle server ? 9 66
How to learn Linux? 10 61
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question