Suppose that I have a function pointer which can be invoked to do some tasks. How can I store the piece of code, to which the pointer is pointing, to a file on disk so I can later load the file and have the function pointer available again?
Use case: This will be done inside a JIT compiler to prevent the future overhead of JIT-ing in the next run of the same program.
Edit: The answer to "Save and load function pointers to file" are not what I am looking for. That question is dealing with a limited number of functions to which people have suggested using indices. But in my case, the function can be anything with any content.
There is no portable way to do that. Your options are:
Associate pointers with symbolic names of your choosing, e.g. using a global mapping table, and serialize the function name. On deserialization, look up the actual pointer in the mapping.
Serialize real function names, possibly also contained with a mapping. On deserialization, use dlsym (or equivalent on non-Unix platforms, such as GetProcAddress) to get the function pointer.
Related
I have a C shared library (in my case, a DLL) that is used for function calls in a very procedural way. In other words, the main application (.exe) makes separate function calls to this DLL at different times. I would like to share the same array variable among certain functions in the DLL. There is a function that allocates and initializes the array. There is another function that uses the array for some computations. But these functions are called from the main application separately. So I can't pass the array from the initialization function to another in the DLL, because each function is invoked separately (at different times).
I'd like to avoid using a global variable. I could do that, and statically define the array to have a large enough size just to be "safe". But large enough may mean unnecessarily very large. I've seen posts suggesting defining the array in a function, but as a static variable and dynamically allocate it in the initialization function call, but I would still need to have access to the same array in other functions.
What is the best way to keep the code general (i.e., with dynamic memory allocation) while ensuring the same array can be accessed from multiple functions?
UPDATE
A few more details after some discussion.
One possible approach would be to keep a handle to the array in the caller (.exe) and pass it to a DLL function when needed. But, from an interface/API perspective, it wouldn't make sense to keep passing this array, because that would require changing function signatures that aren't meant to be changed. The array should really reside in the DLL and be accessible everywhere. I only need to update its contents when calling the initialization function in the DLL. Then the other DLL functions will make use of it internally to the DLL.
Let's say I have a function:
int foo (int A, char B){...}
One of the features I want to implement is the capability for the user to call any function on the application through the Linux terminal. So as an input for the software, in the terminal they type something like:
foo 2 'a'
Then my application parses that, and using the symbol tables it is able to find the address for foo(), as well as the type for all its parameters.
However, I'm not sure how I would pass the parameters to the function when calling it, since I can have hundreds of different parameters types combination depending on the function called.
Any hint how that could be achieved without having hundreds of nested if statements to cast the parameters to the correct types before calling the functions?
That functionality is similar to what GDB has, where you can do call foo(2,'a') and GDB calls that function to you.
There are two approaches to this. If what you described is all you want to do, then you can use the dyncall library so that you dont have to worry about platform/compiler-specific calling semantics yourself:
The dyncall library encapsulates architecture-, OS- and compiler-specific function call semantics in a virtual bind argument parameters from left to right and then call interface allowing programmers to call C functions in a completely dynamic manner. In other words, instead of calling a function directly, the dyncall library provides a mechanism to push the function parameters manually and to issue the call afterwards.
The other approach is, if you might want to do more: e.g. what if an argument cannot be created by a literal? What if the argument is the output of another function? Can you write f(123, g("a")) in your console? Can you write x=g("a"); f(x)? And if(cond) x="a" else x="b"; f(x) In this case you need to embed a scripting language like e.g. LUA.
If you compile your binary with debug information, you can extract it using libdwarf (https://www.prevanders.net/dwarf.html), so for every function you can get a list a parameters with types and you would know how to interpret user's input.
C89
gcc (GCC) 4.7.2
Hello,
I am maintaining someones software and I found this function that returns the address of a static structure. This should be ok as the static would indicate that it is a global so the address of the structure will be available until the program terminates.
DRIVER_API(driver_t*) driver_instance_get(void)
{
static struct tag_driver driver = {
/* Elements initialized here */
};
return &driver;
}
Used like this:
driver_t *driver = NULL;
driver = driver_instance_get();
The driver variable is used throughout the program until it terminates.
some questions:
Is it good practice to do like this?
Is there any difference to declaring it static outside the function at file level?
Why not pass it a memory pool into the function and allocate memory to the structure so that the structure is declared on the heap?
Many thanks for any suggestions,
Generally, no. It makes the function non-reentrable. It can be used with restraint in situations when the code author really knows what they are doing.
Declaring it outside would pollute the file-level namespace with the struct object's name. Since direct access to the the object is not needed anywhere else, it makes more sense to declare it inside the function. There's no other difference.
Allocate on the heap? Performance would suffer. Memory fragmentation would occur. And the caller will be burdened with the task of explicitly freeing the memory. Forcing the user to use dynamic memory when it can be avoided is generally not a good practice.
A better idea for a reentrable implementation would be to pass a pointer to the destination struct from the outside. That way the caller has the full freedom of allocating the recipient memory in any way they see fit.
Of course, what you see here can simply be a C implementation of a singleton-like idiom (and most likely it is, judging by the function's name). This means that the function is supposed to return the same pointer every time, i.e. all callers are supposed to see and share the same struct object through the returned pointer. And, possibly, thy might even expect to modify the same object (assuming no concurrency). In that case what you see here is a function-wrapped implementation of a global variable. So, changing anything here in that case would actually defeat the purpose.
As long as you realize that any code that modifies the pointer returned by the function is modifying the same variable as any other code that got the same pointer is referring to, it isn't a huge problem. That 'as long as' can be a fairly important issue, but it works. It usually isn't the best practice — for example, the C functions such as asctime() that return a pointer to a single static variable are not as easy to use as those that put their result into a user-provided variable — especially in threaded code (the function is not reentrant). However, in this context, it looks like you're achieving a Singleton Pattern; you probably only want one copy of 'the driver', so it looks reasonable to me — but we'd need a lot more information about the use cases before pontificating 'this is diabolically wrong'.
There's not really much difference between a function static and a file static variable here. The difference is in the implementation code (a file static variable can be accessed by any code in the file; the function static variable can only be accessed in the one function) and not in the consumer code.
'Memory pool' is not a standard C concept. It would probably be better, in general, to pass in the structure to be initialized by the called function, but it depends on context. As it stands, for the purpose for which it appears to be designed, it is OK.
NB: The code would be better written as:
driver_t *driver = driver_instance_get();
The optimizer will probably optimize the code to that anyway, but there's no point in assigning NULL and then reassigning immediately.
I have come across the fact that function pointers can be used to implement callbacks. Is there any other usage of function pointers? Is there any other situation that function pointers proved to be useful?
How about sorting? Pass in a function pointer to compare any two elements.
How about filtering? Pass in a function pointer to decide whether an input element should be contained in the output of a filter.
How about transformations? Pass in a function pointer to convert an input element to an output element.
These are all collection-based uses, but they're very useful. (The broad equivalent of function pointers in .NET is delegates, and they're the basis of LINQ, which allows very simple querying, transformations, grouping etc.)
Anywhere you want to be able to abstract out the idea of "a single piece of behaviour", writing a generic function which doesn't need to know the details of that behaviour, a function pointer could be useful.
In addition to what Jon wrote, function pointers in C can be used to implement OO programming style (e.g. polymorphism).
Function pointers (or their typed and more advanced equivalents) are a helpful feature when implementing inversion of control related patterns. All examples mentioned are applications of IoC principle (the sorting algorithm does not control the used predicate, the call to an object method is delayed until run-time etc)
Regards,
Paul
A function pointer is used in any situation where the function to be called is determined at runtime rather than compile-time. This includes callbacks, but may also be used as a switch-case alternative for example, and to adapt the behaviour of a function by passing a function pointer that defines that behaviour - this is how the standard library qsort() function works for example, enabling it to sort any kind of object.
I have used them in particular to implement a command line parser that evaluates C expressions entered as strings at run-time, and can include function calls. This uses a symbol table to lookup the pointer to the function so it can be called on demand from the operator.
All you might ever wish to know on the subject can be found at The Function Pointer Tutorials
In the end function pointers are just one of those rarely used tools you keep in your bag. If you understand them, when the situation arises where it may provide a solution, you will hopefully recognise it.
It is the only way you can implement Higher Order Functions in C.
As others have mentioned, I've found that one of the most significant uses of function pointers (other than for callbacks) is to enable the construction of generic data structures.
Say you want to construct a hashmap with arbitrary keys and values. One way to do that is declare both void *key and void *value and then pass in two function pointers during the initialization phase: int (*hashcode)(void*) and int (*equals)(void*, void*).
This gives you the ability to build a hashmap that can take basically anything that you can write the above two functions for. In my case, the key was a fixed size character buffer and the value was a pointer to a struct.
It is also used in the following
Making jump tables(like vector tables or ISR)
making the function abstract
Developing Finite State Machines (as state, action and triggered even can easily be implemented using the function pointers, the design also seems to be easy and more readable in that)
Event Driven Framework(GUI - gtk is an example)
Other than callbacks (great for abstraction), function pointers can be used to implement polymorphism in C. This is done extensively in the Linux kernel, and common C libraries such as glibc, GTK+ and GLib.
Being a developer born and raised on OO, I was curious to hear how it's possible to avoid global state in a procedural program.
You can also write object-oriented code in C. You don't get all the C++ goodies and it's ugly, and you have to manually pass the this pointer (I've seen self used for this, in order to make it compatible with C++), but it works. So technically, you don't need global state in pure procedural languages for the very same reasons you don't need it in object-oriented languages. You just have to pass the state around explicitly, rather than implicitly like in OO languages.
As an example, look at how the file I/O functions in the C standard library work with pointer to FILE objects that are (largely) opaque. Or look at how OS APIs deal with handles and such to encapsulate information. A program creates objects, uses APIs that act on those objects and closes/deletes the objects - all using straight C.
A global variable is nothing but an implicit procedure argument. Make it explicit and the global variable goes away.
Note: the fact that you no longer use a global variable does not mean that you no longer use global state! What we did above was just a purely syntactical transformation, the semantics of the program haven't changed at all. It's just as non-composable, non-modular, non-threadsafe, non-parallelizable as it was before.
All OO is a mindset and a whole bunch of compiler support.
You can achieve much the same by discipline, coding conventions, and passing around structures in most languages.
For example I used to have functions/procedures prefixed with their module identity, taking the first parameter as being the related module struct.
// System.h
typedef struct _System
{
struct _System *owner;
LinkedList *elements;
} System;
// System.c
int System_FindName ( System * system, char *name)
{
..
}
etc..
I'd really seriously not like to have to go back to coding like this though. I'm very happy that I haven't had to write and debug a linked list for at least 18 years. It was hard back then without the internet and sitting there isolated in the corner of a cold brightly lit room with green phosphors burning into your retina...
Of course. Just declare a struct somewhere, allocate some memory for it, pass the pointer to the allocated memory to an initialization function, and off you go. Just pass the pointer to all the functions that require using the struct.
Though the question arises as to where you store the pointer to the data you don't want to be global, and then you may end up with a global pointer ;-)
You can have variables on stack or in heap that will exist during all the program life.
Passing object style structure pointers to every function is a good way to have OO C coding style.
(I would suggest to have a look in linux sources)
You could try, as an example, create with dia (the diagramming tool), a simple class (for example, a square).
http://projects.gnome.org/dia/
http://dia-installer.de/index_en.html
Then, you can transform that class in C code using dia2code:
http://dia2code.sourceforge.net/
Specifically, say you created the class square inside the square.dia diagram. Then, you type:
$ dia2code -t c square.dia
... and you will see that it is possible to convert any object-oriented programming in a C program without global variables. Explore the created files square.c and square.h
NOTE: in Windows, you'll need a workaround in order to make dia2code work. Before using dia2code, change square.dia to square.zip, unzip it, and rename the result as square.dia
Simple. Whenever a procedure accesses a global variable, then give this variable as an argument to the procedure instead, either by value or by reference or by pointer, or by whatever your programming language provides. After that there is no more need for the variable to be global.