Using Function Pointers to make a firmware patches in C? - c

A few years back I read a blog (now the link is lost in oblivion) and have even seen the example of heavily using the function pointers in developing the patch for the firmware in my previous organisation.
But due to security reasons/NDA signed I couldn't take the copy of code (and I am proud of not doing so and following best practices).
I have seen that the functions are coded in some naming conventions like:
filename_func_<version>_<minor_string>(arguments,other arguments)
and similar file is coded (part of patch) and flashed in the ROM and when the function is called it takes the address of the new definition of the function from the Patch location.
Any idea/detail on this?

The system has to be designed to make this work.
There are various aspects that must be coordinated:
There has to be a way to change the function pointers.
The code has to invoke the functions through the pointers.
There are multiple ways to do it in detail, but they end up being variants on a theme.
/* Declaration of function pointer used to invoke the function */
extern int (*filename_func_ptr)(int arg1, char const *arg2);
/* Two versions of the function */
extern int filename_func_1_1(int arg1, char const *arg2);
extern int filename_func_1_2(int arg1, char const *arg2);
/* Definition of function pointer - pointing to version 1.1 of the function */
int (*filename_func_ptr)(int arg1, char const *arg2) = filename_func_1_1;
/* Use of function pointer */
static void some_function(void)
{
printf("%d\n", (*filename_func_ptr)(1, "pi"));
}
Note that you might never have both filename_func_1_1() and filename_func_1_2() declared in the same file. The effect I'm describing is 'as if'.
After patching, by whatever means you choose, the result is as if you had this written:
int (*filename_func_ptr)(int arg1, char const *arg2) = filename_func_1_2;
You can get into issues with dynamic loading (dlsym(), plus dlopen() etc) to get the new symbols. That would need a file name for the library to dynamically load, plus a way to convert the function names into pointers to the right functions.
Each patchable function needs to be invoked uniformly through the pointer. This is what allows you to replace the function. Consider whether a dynamic (shared) library is sufficient (because it will probably be simpler). If you're on firmware, you probably don't have that luxury.
You need to consider how you'll handle multiple functions with divergent interfaces; will you use single global variables as shown here, or some generic function pointer type which has to be cast appropriately at each invocation, or a union type, or a structure holding pointers, or ... There are a lot of ways of organizing things.

Related

Determining to which function a pointer is pointing in C?

I have a pointer to function, assume any signature.
And I have 5 different functions with same signature.
At run time one of them gets assigned to the pointer, and that function is called.
Without inserting any print statement in those functions, how can I come to know the name of function which the pointer currently points to?
You will have to check which of your 5 functions your pointer points to:
if (func_ptr == my_function1) {
puts("func_ptr points to my_function1");
} else if (func_ptr == my_function2) {
puts("func_ptr points to my_function2");
} else if (func_ptr == my_function3) {
puts("func_ptr points to my_function3");
} ...
If this is a common pattern you need, then use a table of structs instead of a function pointer:
typedef void (*my_func)(int);
struct Function {
my_func func;
const char *func_name;
};
#define FUNC_ENTRY(function) {function, #function}
const Function func_table[] = {
FUNC_ENTRY(function1),
FUNC_ENTRY(function2),
FUNC_ENTRY(function3),
FUNC_ENTRY(function4),
FUNC_ENTRY(function5)
}
struct Function *func = &func_table[3]; //instead of func_ptr = function4;
printf("Calling function %s\n", func->func_name);
func ->func(44); //instead of func_ptr(44);
Generally, in C such things are not available to the programmer.
There might be system-specific ways of getting there by using debug symbols etc., but you probably don't want to depend on the presence of these for the program to function normally.
But, you can of course compare the value of the pointer to another value, e.g.
if (ptr_to_function == some_function)
printf("Function pointer now points to some_function!\n");
The function names will not be available at runtime.
C is not a reflective language.
Either maintain a table of function pointers keyed by their name, or supply a mode of calling each function that returns the name.
The debugger could tell you that (i.e. the name of a function, given its address).
The symbol table of an unstripped ELF executable could also help. See nm(1), objdump(1), readelf(1)
Another Linux GNU/libc specific approach could be to use at runtime the dladdr(3) function. Assuming your program is nicely and dynamically linked (e.g. with -rdynamic), it can find the symbol name and the shared object path given some address (of a globally named function).
Of course, if you have only five functions of a given signature, you could compare your address (to the five addresses of them).
Notice that some functions don't have any ((globally visible) names, e.g. static functions.
And some functions could be dlopen-ed and dlsym-ed (e.g. inside plugins). Or their code be synthetized at runtime by some JIT-ing framework (libjit, gccjit, LLVM, asmjit). And the optimizing compiler can (and does!) inline functions, clone them, tail-call them, etc.... so your question might not make any sense in general...
See also backtrace(3) & Ian Taylor's libbacktrace inside GCC.
But in general, your quest is impossible. If you really need such reflective information in a reliable way, manage it yourself (look into Pitrat's CAIA system as an example, or somehow my MELT system), perhaps by generating some code during the build.
To know where a function pointer points is something you'll have to keep track of with your program. Most common is to declare an array of function pointers and use an int variable as index of this array.
That being said, it is nowadays also possible to tell in runtime which function that is currently executed, by using the __func__ identifier:
#include <stdio.h>
typedef const char* func_t (void);
const char* foo (void)
{
// do foo stuff
return __func__;
}
const char* bar (void)
{
// do bar stuff
return __func__;
}
int main (void)
{
func_t* fptr;
fptr = foo;
printf("%s executed\n", fptr());
fptr = bar;
printf("%s executed\n", fptr());
return 0;
}
Output:
foo executed
bar executed
Not at all - the symbolic name of the function disappears after compilation. Unlike a reflective language, C isn't aware of how its syntax elements were named by the programmer; especially, there's no "function lookup" by name after compilation.
You can of course have a "database" (e.g. an array) of function pointers that you can compare your current pointer to.
This is utterly awful and non-portable, but assuming:
You're on Linux or some similar, ELF-based system.
You're using dynamic linking.
The function is in a shared library or you used -rdynamic when linking.
Probably a lot of other assumptions you shouldn't be making...
You can obtain the name of a function by passing its address to the nonstandard dladdr function.
set your linker to output a MAP file.
pause the program
inspect the address contained in the pointer.
look up the address in the MAP file to find out which function is being pointed to.
A pointer to a C function is an address, like any pointer. You can get the value from a debugger. You can cast the pointer to any integer type with enough bits to express it completely, and print it. Any compilation unit that can use the pointer, ie, has the function name in scope, can print the pointer values or compare them to a runtime variable, without touching anything inside the functions themselves.

What are some practical uses for const-qualified variables in C?

As has been discussed in several recent questions, declaring const-qualified variables in C (as opposed to const variables in C++, or pointers to const in C) usually serves very little purpose. Most importantly, they cannot be used in constant expressions.
With that said, what are some legitimate uses of const qualified variables in C? I can think of a few which have come up recently in code I've worked with, but surely there must be others. Here's my list:
Using their addresses as special sentinel values for a pointer, so as never to compare equal to any other pointer. For example: char *sentinel(void) { static const char s; return &s; } or simply const char sentinel[1]; Since we only care about the address and it actually wouldn't matter if the object were written to, the only benefit of const is that compilers will generally store it in read-only memory that's backed by mmap of the executable file or a copy of the zero page.
Using const qualified variables to export values from a library (especially shared libraries), when the values could change with new versions of the library. In such cases, simply using #define in the library's interface header would not be a good approach because it would make the application dependent on the values of the constants in the particular version of the library it was built with.
Closely related to the previous use, sometimes you want to expose pre-defined objects from a library to the application (the quintessential examples being stdin, stdout, and stderr from the standard library). Using that example, extern FILE __stdin; #define stdin (&__stdin) would be a very bad implementation due to the way most systems implement shared libraries - usually they require the entire object (here, FILE) to be copied to an address determined when the application is linked, and introduce a dependency on the size of the object (the program will break if the library is rebuilt and the size of the object changes). Using a const pointer (not pointer-to-const) here fixes all the problems: extern FILE *const stdin;, where the const pointer is initialized to point to the pre-defined object (which itself is likely declared static) somewhere internal to the library.
Lookup tables for mathematical functions, character properties, etc. This is the obvious one I originally forgot to include, probably because I was thinking of individual const variables of arithmetic/pointer type, as that's where the question topic first came up. Thanks to Aidan for triggering me to remember.
As a variant on lookup tables, implementation of state machines. Aidan provided a detailed example as an answer. I've found the same concept is also often very useful without any function pointers, if you can encode the behavior/transitions from each state in terms of a few numeric parameters.
Anyone else have some clever, practical uses for const-qualified variables in C?
const is quite often used in embedded programming for mapping onto GPIO pins of a microcontroller. For example:
typedef unsigned char const volatile * const tInPort;
typedef unsigned char * const tOutPort;
tInPort my_input = (tInPort)0x00FA;
tOutPort my_output = (tOutPort)0x00FC;
Both of these prevent the programmer from accidentally changing the pointer itself which could be disastrous in some cases. The tInPort declaration also prevents the programmer from changing the input value.
Using volatile prevents the compiler from assuming that the most recent value for my_input will exist in cache. So any read from my_input will go directly to the bus and hence always read from the IO pins of the device.
For example:
void memset_type_thing(char *first, char *const last, const char value) {
while (first != last) *(first++) = value;
}
The fact that last can't be part of a constant-expression is neither here nor there. const is part of the type system, used to indicate a variable whose value will not change. There's no reason to modify the value of last in my function, so I declare it const.
I could not bother declaring it const, but then I could not bother using a statically typed language at all ;-)
PC-lint warning 429 follows from the expectation that a local pointer to an allocated object should be consumed
by copying it to another pointer or
by passing it to a "dirty" function (this should strip the "custodial" property of the pointer) or
by freeing it or
by passing it up the caller through a return statement or a pass-by-pointer parameter.
By "dirty" I mean a function whose corresponding pointer parameter has a non-const base type. The description of the warning absolves library functions such as strcpy() from the "dirty" label, apparently because none of such library functions takes ownership of the pointed object.
So when using static analysis tools such as PC-lint, the const qualifier of parameters of called functions keeps locally allocated memory regions accounted.
const can be useful for some cases where we use data to direct code in a specific way. For example, here's a pattern I use when writing state machines:
typedef enum { STATE1, STATE2, STATE3 } FsmState;
struct {
FsmState State;
int (*Callback)(void *Arg);
} const FsmCallbacks[] = {
{ STATE1, State1Callback },
{ STATE2, State2Callback },
{ STATE3, State3Callback }
};
int dispatch(FsmState State, void *Arg) {
int Index;
for(Index = 0; Index < sizeof(FsmCallbacks)/sizeof(FsmCallbacks[0]); Index++)
if(FsmCallbacks[Index].State == State)
return (*FsmCallbacks[Index].Callback)(Arg);
}
This is analogous to something like:
int dispatch(FsmState State, void *Arg) {
switch(State) {
case STATE1:
return State1Callback(Arg);
case STATE2:
return State2Callback(Arg);
case STATE3:
return State3Callback(Arg);
}
}
but is easier for me to maintain, especially in cases where there's more complicated behavior associated with the states. For example, if we wanted to have a state-specific abort mechanism, we'd change the struct definition to:
struct {
FsmState State;
int (*Callback)(void *Arg);
void (*Abort)(void *Arg);
} const FsmCallbacks[] = {...};
and I don't need to modify both the abort and dispatch routines for the new state. I use const to prevent the table from changing at runtime.
A const variable is useful when the type is not one that has usable literals, i.e., anything other than a number. For pointers, you already give an example (stdin and co) where you could use #define, but you'd get an lvalue that could easily be assigned to. Another example is struct and union types, for which there are no assignable literals (only initializers). Consider for instance a reasonable C89 implementation of complex numbers:
typedef struct {double Re; double Im;} Complex;
const Complex Complex_0 = {0, 0};
const Complex Complex_I = {0, 1}; /* etc. */
Sometimes you just need to have a stored object and not a literal, because you need to pass the data to a polymorphic function that expects a void* and a size_t. Here's an example from the cryptoki API (a.k.a. PKCS#11): many functions require a list of arguments passed as an array of CK_ATTRIBUTE, which is basically defined as
typedef struct {
CK_ATTRIBUTE_TYPE type;
void *pValue;
unsigned long ulValueLen;
} CK_ATTRIBUTE;
typedef unsigned char CK_BBOOL;
so in your application, for a boolean-valued attribute you need to pass a pointer to a byte containing 0 or 1:
CK_BBOOL ck_false = 0;
CK_ATTRIBUTE template[] = {
{CKA_PRIVATE, &ck_false, sizeof(ck_false)},
... };
They can be used for memory-mapped peripherals or registers that cannot be changed by user code, only some internal mechanism of the microprocessor. Eg. on the PIC32MX, certain registers indicating program state are qualified const volatile - so you can read them, and the compiler won't try to optimise out, say, repeated accesses, but your code cannot write to them.
(I don't any code to hand, so I can't cite a good example right now.)

dlsym/dlopen with runtime arguments

I am trying to do something like the following
enum types {None, Bool, Short, Char, Integer, Double, Long, Ptr};
int main(int argc, char ** args) {
enum types params[10] = {0};
void* triangle = dlopen("./foo.so", RTLD_LAZY);
void * fun = dlsym(triangle, ars[1]);
<<pseudo code>>
}
Where pseudo code is something like
fun = {}
for param in params:
if param == None:
fun += void
if param == Bool:
fun += Boolean
if param == Integer:
fun += int
...
returnVal = fun.pop()
funSignature = returnval + " " + funName + "(" + Riffle(fun, ",") + ")"
exec funSignature
Thank you
Actually, you can do nearly all you want. In C language (unlike C++, for example), the functions in shared objects are referenced merely by their names. So, to find--and, what is most important, to call--the proper function, you don't need its full signature. You only need its name! It's both an advantage and disadvantage --but that's the nature of a language you chose.
Let me demonstrate, how it works.
#include <dlfcn.h>
typedef void* (*arbitrary)();
// do not mix this with typedef void* (*arbitrary)(void); !!!
int main()
{
arbitrary my_function;
// Introduce already loaded functions to runtime linker's space
void* handle = dlopen(0,RTLD_NOW|RTLD_GLOBAL);
// Load the function to our pointer, which doesn't know how many arguments there sould be
*(void**)(&my_function) = dlsym(handle,"something");
// Call something via my_function
(void) my_function("I accept a string and an integer!\n",(int)(2*2));
return 0;
}
In fact, you can call any function that way. However, there's one drawback. You actually need to know the return type of your function in compile time. By default, if you omit void* in that typedef, int is assumed as return type--and, yes, it's a correct C code. The thing is that the compiler needs to know the size of the return type to operate the stack properly.
You can workaround it by tricks, for example, by pre-declaring several function types with different sizes of return types in advance and then selecting which one you actually are going to call. But the easier solution is to require functions in your plugin to return void* or int always; the actual result being returned via pointers given as arguments.
What you must ensure is that you always call the function with the exact number and types of arguments it's supposed to accept. Pay closer attention to difference between different integer types (your best option would be to explicitly cast arguments to them).
Several commenters reported that the code above is not guaranteed to work for variadic functions (such as printf).
What dlsym() returns is normally a function pointer - disguised as a void *. (If you ask it for the name of a global variable, it will return you a pointer to that global variable, too.)
You then invoke that function just as you might using any other pointer to function:
int (*fun)(int, char *) = (int (*)(int, char *))dlsym(triangle, "function");
(*fun)(1, "abc"); # Old school - pre-C89 standard, but explicit
fun(1, "abc"); # New school - C89/C99 standard, but implicit
I'm old school; I prefer the explicit notation so that the reader knows that 'fun' is a pointer to a function without needing to see its declaration. With the new school notation, you have to remember to look for a variable 'fun' before trying to find a function called 'fun()'.
Note that you cannot build the function call dynamically as you are doing - or, not in general. To do that requires a lot more work. You have to know ahead of time what the function pointer expects in the way of arguments and what it returns and how to interpret it all.
Systems that manage more dynamic function calls, such as Perl, have special rules about how functions are called and arguments are passed and do not call (arguably cannot call) functions with arbitrary signatures. They can only call functions with signatures that are known about in advance. One mechanism (not used by Perl) is to push the arguments onto a stack, and then call a function that knows how to collect values off the stack. But even if that called function manipulates those values and then calls an arbitrary other function, that called function provides the correct calling sequence for the arbitrary other function.
Reflection in C is hard - very hard. It is not undoable - but it requires infrastructure to support it and discipline to use it, and it can only call functions that support the infrastructure's rules.​​​​
The Proper Solution
Assuming you're writing the shared libraries; the best solution I've found to this problem is strictly defining and controlling what functions are dynamically linked by:
Setting all symbols hidden
for example clang -dynamiclib Person.c -fvisibility=hidden -o libPerson.dylib when compiling with clang
Then using __attribute__((visibility("default"))) and extern "C" to selectively unhide and include functions
Profit! You know what the function's signature is. You wrote it!
I found this in Apple's Dynamic Library Design Guidelines. These docs also include other solutions to the problem above was just my favorite.
The Answer to your Question
As stated in previous answers, C and C++ functions with extern "C" in their definition aren't mangled so the function's symbols simply don't include the full function signature. If you're compiling with C++ without extern "C" however functions are mangled so you could demangle them to get the full function's signature (with a tool like demangler.com or a c++ library). See here for more details on what mangling is.
Generally speaking it's best to use the first option if you're trying to import functions with dlopen.

What does ... mean in an argument list in C?

I came across the following function signature and I wondered if this (the ellipsis, or "...") is some kind of polymorphism?
#include <fcntl.h>
int fcntl(int fd, int cmd, ... );
Thanks in advance.
It's a variable argument list.
That is a variadic function. See stdarg.h for more details.
The ... means that you can pass any number of arguments to this function, as other commenters have already mentioned. Since the optional arguments are not typed, the compiler cannot check the types and you can technically pass in any argument of any type.
So does this mean you can use this to implement some kind of polymorphic function? (I.e., a function that performs some operation based on the type of its arguments.)
No.
The reason you cannot do this, is because you cannot at runtime inspect the types of the arguments passed in. The function reading in the variable argument list is expected to already know the types of the optional arguments it is going to receive.
In case of a function that really is supposed to be able to take any number of arguments of any type (i.e., printf), the types of the arguments are passed in via the format string. This means that the caller has to specify the types it is going to pass in at every invocation, removing the benefit of polymorphic functions (that the caller doesn't have to know the types either).
Compare:
// Ideal invocation
x = multiply(number_a, number_b)
y = multiply(matrix_a, matrix_b)
// Standard C invocation
x = multiply_number(number_a, number_b)
y = multiply_matrix(matrix_a, matrix_b)
// Simulated "polymorphism" with varargs
x = multiply(T_NUMBER, number_a, number_b)
y = multiply(T_MATRIX, matrix_a, matrix_b)
You have to specify the type before the varargs function can do the right thing, so this gains you nothing.
No, that's the "ellipsis" you're seeing there, assuming you're referring to the ... part of the declaration.
Basically it says that this function takes an unknown number of arguments after the first two that are specified there.
The function has to be written in such a way that it knows what to expect, otherwise strange results will ensue.
For other functions that support this, look at the printf function and its variants.
Does C support polymorphism?
No, it doesn't.
However there are several libraries, such as Python C API, that implements a rough variant of polymorphism using structs and pointers. Beware that compiler cannot perform appropriate type checking in most cases.
The tecnhique is simple:
typedef struct {
char * (*to_string)();
} Type;
#define OBJ_HEADER Type *ob_type
typedef struct {
OBJ_HEADER;
} Object;
typedef struct {
OBJ_HEADER;
long ival;
} Integer;
typedef struct {
OBJ_HEADER;
char *name;
char *surname;
} Person;
Integer and Person get a Type object with appropriate function pointers (e.g. to functions like integer_to_string and person_to_string).
Now just declare a function accepting an Object *:
void print(Object *obj) {
printf("%s", obj->type->to_string());
}
now you can call this function with both an Integer and a Person:
Integer *i = make_int(10);
print((Object *) i);
Person *p = make_person("dfa");
print((Object *) p);
EDIT
alternatively you can declare i and p as Object *; of course make_int and make_person will allocate space for Integer and Person and do the appropriate cast:
Object *
make_integer(long i) {
Integer *ob = malloc(sizeof(Integer));
ob->ob_type = &integer_type;
ob->ival = i;
return (Object *) ob;
}
NB: I cannot compile these examples rigth now, please doublecheck them.
I came across the following function signature and I wondered if this (the ellipsis, or "...") is some kind of polymorphism?
yes, it is a primitive form of polymorphism. With only one function signature you are able to pass various structures. However the compiler cannot help you with detecting type errors.
Adding to what's been said: C supports polymorphism through other means. For example, take the standard library qsort function which sorts data of arbitrary type.
It is able to do so by means of untyped (void) pointers to the data. It also needs to know the size of the data to sort (provided via sizeof) and the logic that compares the objects' order. This is accomplished by passing a function pointer to the qsort function.
This is a prime example of runtime polymorphism.
There are other ways to implement object-oriented behaviour (in particular, virtual function calls) by managing the virtual function tables manually. This can be done by storing function pointers in structures and passing them around. Many APIs do so, e.g. the WinAPI, which even uses advanced aspects of object orientation, e.g. base class call dispatch (DefWindowProc, to simulate calling the virtual method of the base class).
I assume you are referring to the ellipsis (...)? If so this indicates that 0 or more parameters will follow. It is called varargs, defined in stdarg.h
http://msdn.microsoft.com/en-us/library/kb57fad8.aspx
printf uses this functionality. Without it you wouldn't be able to keep adding parameters to the end of the function.
C supports a crude form of Polymorphism. I.e. a type being able to appear and behave as another type. It works in a similar was as in C++ under the hood (relying on memory being aligned) but you have to help the compiler out by casting. E.g. you can define a struct:
typedef struct {
char forename[20];
char surname[20];
} Person;
And then another struct:
typedef struct {
char forename[20];
char surname[20];
float salary;
char managername[20];
} Employee;
Then
int main (int argc, int *argv)
{
Employee Ben;
setpersonname((Person *) &Ben);
}
void setpersonname(Person *person)
{
strcpy(person->forename,"Ben");
}
The above example shows Employee being used as a Person.
No, it is a function that is taking variable number of arguments.
That is not technically polymorphism. fcntl takes variable number of arguments & that is the reason for the ... similar to printf function.
C neither supports function overloading - which is a type of ad-hoc polymorphism based on compile-time types - nor multiple dispatch (ie overloading based on runtime types).
To simulate function overloading in C, you have to create multiple differently named functions. The functions' names often contain the type information, eg fputc() for characters and fputs() for strings.
Multiple dispatch can be implemented by using variadic macros. Again, it's the programmer's job to provide the type information, but this time via an extra argument, which will be evaluated at runtime - in contrast to the compile-time function name in case of the approach given above. The printf() family of functions might not be the best example for multiple dispatch, but I can't think of a better one right now.
Other approaches to multiple dispatch using pointers instead of variadic functions or wrapping values in structures to provide type annotations exist.
The printf declaration in the standard library is
int printf(const char*, ...);
Think about that.
You can write code that supports Polymorphic behavior in C, but the ... (ellipsis) is not going to be much help. That is for variable arguments to a function.
If you want polymorphic behavior you can use, unions and structures to construct a data structure that has a "type" section and variable fields depending on type. You can also include tables of function pointers in the structures. Poof! You've invented C++.
Yes C Do support the polymorphism
the Code which we write in the C++ using virtual to implement the polymorphism
if first converted to a C code by Compiler (one can find details here).
It's well known that virtual functionality in C++ is implemented using function pointers.

C RPC without the stubs

I have this program that I want other processes to be able to call functions on (through unix sockets). The message protocol is very simple, the function name, a function signature, and a buffer (char *) that holds the parameters.
When a module in my program wants to allow a function to be accessible, it registers the name and signature with the library. The problem I'm facing is with physically calling the function once the request comes in. I have looked at RPC and java RMI-like libraries, but those require that I generate stubs to wrap calls. The system I am working on is very dynamic and I also have to interface with other peoples code that I can't modify.
So basically, a function might look like:
int somefunc(int someparam, double another)
{
return 1234;
}
now I register with the library:
// func ptr name signature
REG_FUNCTION(somefunc, "somefunc", "i:id");
When the request comes in, I do some error checking, once valid I want to call the function. So I have the variables:
void * funcptr = (the requested function);
char * sig = (the function signature);
char * params = (a buffer of function parameters);
//note that the params buffer can hold data types of arbitrary lengths
How can I call the function with the parameters in C?
Thanks!
I don't think this is completely solvable in general, using only C. You don't know the calling convention used by the target function, for instance. There is a risk that you end up "cheating" the compiler, or at least having to second-guess it. What if the compiler decided to build the registered function using arguments passed in registers, perhaps due to some optimization setting (or what if it was built with a different compiler?).
There's also no way in general to express in C that you want to call a function with a given set of arguments, and that the values for the arguments need to be unpacked from a buffer of random bytes.
You could do something horrible like this:
enum { VOID_INT, VOID_INT_DOUBLE, VOID_DOUBLE_INT, ... } Signature;
void do_call(const void *userfunction, const void *args, Signature sig)
{
switch(signature)
{
case VOID_INT:
{
int x = *(int *) args;
void (*f)(int) = userfunction;
f(x);
break;
}
case VOID_INT_DOUBLE:
...
}
}
But it's quite clear that this doesn't live on the same continent as scalability. You could of course auto-generate this code, for some reasonable set of return types and argument types. You'd still be a bit out in the cold for casting function pointers to/from void *, but that might be acceptable. You'd still always run the risk of someone handing you a signature that you don't have pre-generated code for, though.
Check out libffi. This library allows to call function with a set of parameters specified at runtime.

Resources