-1

I have an issue with a customer. He's asking me to set up a DB table with key/values where the values are names of C functions. He wants me to build a generic executable that will take the records of that table and call the functions stored into a C library. He wants to be able to insert or update new pairs of key/values and without modifying the executable, be able to change the function called.

As an example, I wil l post now something very similar:

int sum(int a, int b)
{
  return a+b;
}

int sub(int a, int b)
{
  return a-b;
}

int (*funcion) (int,int);


{
  ...
  funcion = (void*)"sum";     
  x = funcion(4,3);   
  funcion = (void*)"sub";
  x = funcion(4,3);     
}

Is this going to work? Thanks!

  • 3
    I'd say that's "optimistic" at best. Maybe if you combine this approach with `dlsym`? – Kerrek SB Nov 21 '14 at 12:32
  • 2
    Probably the best way would be to use a [dynamically linked library](https://en.wikipedia.org/wiki/Dynamic_loading), then you can look up functions by name (using e.g. `dlsym` on proper operating systems, or `GetProcAddress` on Windows). – Paul R Nov 21 '14 at 12:33
  • 2
    You need a mapping from persistent function-handle (Which might be the name or an array-index) to function-pointer, in your program. Either using the dynamic loader or manually. The first is easier automated, the second safer. – Deduplicator Nov 21 '14 at 12:34
  • 2
    Just drop the "" add some types and you are almost there. – 2501 Nov 21 '14 at 12:35
  • @2501: I think you must have missed the part about "inserting or updating new pairs without modifying the executable". – Paul R Nov 21 '14 at 12:36
  • Hey! Thanks to you all! I think that the smartest solution here is to convince him this is not a good idea... :P – Alberto Ojedo Nov 21 '14 at 12:43
  • 1
    That **dlsym** thing looks great. It's a Solaris server. I'll have a look at it, but I don't have much time :( – Alberto Ojedo Nov 21 '14 at 12:45
  • Take a look to http://stackoverflow.com/questions/6617679/using-dlopen-on-an-executable where you can find some other pointer where start. – Michele d'Amico Nov 21 '14 at 12:48

1 Answers1

0

You need a "lookup table". The problem is that you need to define all functions which could be called before compilation. In order to add new functions you need to change the code. But if thats ok for you this should do the job.

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

typedef enum
{
    _printf,
    _scanf,
} functions;

void *get_function_ptr(int func)
{
    switch (func)
    {
        case _printf:   return &printf;
        case _scanf:    return &scanf;
        default:        return NULL;
    }
}

int main(int argc, char **argv)
{
    if (strcmp(argv[1], "printf") == 0)
    {
        void (*ptr)(char *, char *) = get_function_ptr(_printf);
        (*ptr)("%s", "hi there");
    }
}

Another way would, as in the comment above said, a dynamic linked library, but then you are OS dependend.

LMF
  • 463
  • 2
  • 10
  • The thing here is that I already have a library with all the functions that **could be called**, so I think that using **dlsym** will work. Does **dlsym** work in Solaris? Is this **dlsym** a standard C library? – Alberto Ojedo Nov 21 '14 at 13:00
  • **dlsym** is not part of the standard C library, but standard of the POSIX/UNIX API and it works under Solaris. But if you do know all functions which could be called (and the library will not change) you can just use my approach. – LMF Nov 21 '14 at 13:06
  • Just came back from a meeting. My customer priority is to finish the code ASAP, so we will codify all the possible function calls in code and end of the story ¬¬ Thanks to you all!!!! – Alberto Ojedo Nov 21 '14 at 13:43