I'm looking for something similar to C++'s boost::bind but in C. What I want is to be able to:
bound_function = bind(my_function, some_param);
and have:
bound_function(something);
execute
myfunction(some_param, something);
So basically, whatever is bound to the function pointer will always be passed as the first parameter to the function.
Is there any way to do this in C?
Don't do this at home kids.
You couldn't do it the way C++ does it, because in boost::bind's case, a class is generated using TMP that holds the actual bound value.
I'm not aware of any way to accomplish anything similar in C. Most C APIs with callbacks like this will pass around a void * for your use to get around issues like this.
The closest you can get is something like this:
#include <stdio.h>
#include <stdlib.h>
typedef void (*function)(void*);
typedef struct {
void *arg;
function fn;
} binder;
binder *binder_create(function fn, void *arg)
{
binder *b = malloc(sizeof(binder));
if (b) {
b->fn = fn;
b->arg = arg;
}
return b;
}
void binder_delete(binder *b)
{
free(b);
}
void binder_exec(binder *b)
{
b->fn(b->arg);
}
int main(void)
{
binder *myfunc = binder_create((function)puts, "Hello, World!\n");
binder_exec(myfunc);
binder_delete(myfunc);
return 0;
}
It doesn't give you function call like syntax (you need to call binder_exec instead), and you would probably need to create several versions that take more arguments and arguments of different types.
In a word, no. C has no such concept.
Related
I have done some research about how to use function pointers in C and I was trying to do some model of an object-oriented kind of thing. So to model such a thing I have been told I would have to add function pointers to the structs, so that they would be kind of 'an object'.
As I am pretty new on programming in C, this question may seem a little stupid (or very easy to answer), but on the Internet, I just found examples concerning C++ and that's not what I am searching.
Here is an example I would like to show, so that you can easily understand what my question is about:
try.h-file:
struct thing {
void (*a)(int, int);
};
void add(int x, int y);
try.c-file:
#include <stdio.h>
#include <stdlib.h>
#include "try.h"
void add(int x, int y) {
printf("x + y = %d\n", x+y);
}
int main(int argc, char* argv[]) {
struct thing *p = (struct thing*) malloc(sizeof(struct thing));
p->a = &add;
(*p->a)(2, 3);
free(p);
p = NULL;
return 0;
}
As an example I would want to have always x = 2, so the function pointer in struct thing would be this kind of pointer: void (*a)(int) and not void (*a)(int, int) anymore.
How can I bind the argument x = 2 when passing the function pointer to the struct (line p->a = &add;)? Is this even possible in C? In C++ I have seen something like std::bind, but I wasn't able to do this in C.
The function pointer has to have the same signature (type and arguments) as the function it points to, so you can't really do it like that.
You could wrap the bind and the call in another couple of functions:
struct thing {
void (*a)(int, int);
int x;
};
...
void bind1st( struct thing *p, int arg )
{
p->x = arg;
}
void call( struct thing *p, int arg )
{
p->a( p->x, arg );
}
You'll want to experiment with this a bit, but that should get you started.
I've had similar problems,and I used the following method to resolve, use gcc to compile it work, use clang to compile it do not work.
#include <stdio.h>
typedef int (*add_t) (int);
add_t add2(int x) {
int add1(int y) {
return x + y;
}
return add1;
}
int main() {
//add2(2);
printf("%d\n", add2(2)(3));
}
A way that no one have talked about yet is to use some JIT logic (I won't provide a working example right now, because I've not yet tried it, but I will use it at some time for a RPC library). This is not strictly speaking a C language feature, and it's feasible only on CPU/MCU architecture where you can write to an executable memory segment (it's possible on x86_64, x86, some ARMs etc.).
The principle is really just to construct a function dynamically that will call the wrapped function in a similar way python defines dynamically nested functions.
Some library you can use for it : libgccjit, libjit, gnu-ligthning, llvm etc.
I think this is the best solution .
typedef void(*call_type)();
call_type bind(void (*f)(int,int), int a, int b) {
void call() {
f(a,b);
}
return &call;
}
void f(int a, int b){
printf("%d, %d", a, b);
}
int main(){
call_type c = bind(f, 5, 4);
c();
}
I have come across the line of code shown below.
I think it may be a cast to a function pointer that returns void and takes a void pointer. Is that correct?
(void (*)(void *))SGENT_1_calc
Yes, it is correct. I find that not very readable, so I suggest declaring the signature of the function to be pointed:
typedef void sigrout_t(void*);
I also have the coding convention that types ending with rout_t are such types for functions signatures. You might name it otherwise, since _t is a suffix reserved by POSIX.
Later on I am casting, perhaps to call it like
((sigrout_t*) SGENT_1_calc) (someptr);
Yes, it is. The function should be looking like this
void func(void*);
But the statement is missing a target, since a cast to nothing is useless. So it should be like
func = (void (*)(void *))SGENT_1_calc;
None of the existing answers show it in direct usage, that is, taking a function pointer and casting it in order to call the function. I was playing with this to show the content of my object as json, accessing both the function and the data through anonymous pointers:
#include <stdio.h>
#include <stdlib.h>
typedef struct box1_s{
int a;
char b[50];
}box1_t;
void box1_t_print(void* ptr){
box1_t* box = (box1_t*)ptr;
printf("{\"a\": %i, \"b\": \"%s\"}", box->a, box->b);
}
int main(){
void* print = (void*)box1_t_print;
box1_t mybox = {3, "Hi folks, it's me!"};
void* ptr = &mybox;
printf("mybox = ");
((void (*)(void*))print)(ptr);
return 0;
}
Output of the program:
mybox = {"a": 3, "b": "Hi folks, it's me!"}
Yes, this is a function pointer cast.
Function pointer casts
To help you with casting functions to pointers, you can define an alias for a function pointer type as follows:
typedef void void_to_void_fct(void*);
You can also define a type for a function that takes and returns values:
typedef int math_operator(int, int);
Later, you can store a function into a function pointer type like this:
void mystery(void* arg) {
// do something nasty with the given argument
};
int add(int a, int b) {
return a + b;
}
void_to_void *ptr1 = mystery;
math_operator *ptr2 = add;
Sometimes, you have a function like print_str :
void print_str(char* str) {
printf("%s", str);
}
and you want to store it in your function pointer that is agnostic to the argument type. You can then use a cast like this:
(void (*)(void *))print_str
or
(void_to_void_fct*)print_str
Why do we use function pointers?
Function pointers allow you to "store a function" inside a variable (indeed, you store the address of the function). This is very convenient when you want to allow some code to have diferent behavior depending on user input.
For exemple, suppose we have some data and some way to decode it. We could have the following structure to keep this information:
typedef char* decoder_type(char*);
struct encoded_data {
char* data;
decoder_type *decoder_fct;
};
char* decoding_function_1(char* data) {
//...
char* decoding_function_2(char* data) {
//...
This allows storing both the data and the function to later use them together to decode the data.
This should be a simple question, but I might not be able to word it correctly or I might be trying to defy the principles of the C language because of my lack of experience with it.
All I want to do is, given a pointer to a function, to wrap it inside another function that takes a pointer to a function as an argument, and make a pointer of the later. Better in code:
void do_nothing_1() {}
void do_nothing_2() {}
void wrapper(void(*f)()) { f(); }
int main() {
// the following will call the function
// but i just want a pointer of whats being called
funcion_pointer_1 = wrapper(do_nothing_1);
funcion_pointer_2 = wrapper(do_nothing_2);
return 0;
}
I apologize beforehand if the question doesn't make any sense, please help me clarify it rather than simply downvote it.
Edit: Given the apparent difficulty to obtain the results desired because of the obscurity of the requirements, I will be a little more specific on what I am looking for.
Inside a struct, I have a pointer to a function:
struct my_struct {
int (* run)(void);
}
What I want to do is to modify that function and that's why I use the wrapper. So, for example, if foo returns void change that to int. Also, run some code before executing foo:
int wrapper(void (*foo)()) {
// exec some stuff here
foo();
return 0;
}
Ultimately, what I want is that when I execute the function corresponding to the *run pointer from my structure, execute some stuff before doing run() and change the return type.
When struggling with the correct syntax, it is helpful to use typedefs to make things clearer. Not just for yourself as you write the code, but for anyone who needs to maintain it, or just try to figure out what it's doing.
You want a function pointer to a function that takes another function pointer as an argument. Start with the argument, a function without parameters and no return value:
typedef void (*void_handler_t)( void);
And now the wrapper function pointer, one that takes a function pointer parameter and has no return value:
typedef void (*wrapper_handler_t)( void_handler void_fn);
And the code:
void foo( void) {}
void wrapper( void_handler_t wrapped_fn)
{
wrapped_fn();
}
int main( int argc, char *argv[])
{
wrapper_handler_t function_pointer;
function_pointer = &wrapper;
function_pointer( &foo);
return 0;
}
I've declared many functions in one driver, and am passing the pointers to the functions to another driver in a list with the node format:
struct node
{
char def_prototype[256]; //example:(int (*)(wchar, int, int))
void *def_function;
};
Is there a way to typecast def_function to the prototype given in def_prototype?
Currently I'm using simple switch and strcmp, but I wanted to generalize it if possible.
PS: I know that casting between void pointer and function pointer is unsafe (as mentioned in various places in SO), but desperate times call for desperate measures and I have taken lot of care.
EDIT:
Sorry for the lack in clarity. I want to actually call the function (not just cast it), making a function pointer at runtime based on the char[] provided.
EDIT AGAIN:
Since I'm working at the kernel level (windows driver), I don't have access to much resources, so, I'm sticking to my current implementation (with some changes to kill back-doors). Thanks to all for your help.
ISO-C does not allow casting between function and data pointers, ie you should use a void (*)(void) instead of a void * to hold your function.
That aside, YeenFei is correct in his assertion that there is no general platform-independant solution, meaning the best you can do in C itself is to supply a list of supported signatures.
You should implement your own encoding scheme instead of using plain C prototypes. It's common to use a string where each char represents a function argument (and the first one the return value); a function of type int (*)(wchar, int, int) for example could have the signature "iwii".
Signature lookup tables can then be easily built using bsearch() and strcmp(); here's a complete example:
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int cmp(const void *key, const void *element)
{
return strcmp(key, *(const char * const *)element);
}
static _Bool dispatch(const char *sig, void (*func)(void), void *retval, ...)
{
// supported signatures; must be ordered according to strcmp()
static const char * const SIGS[] = { "iii", "v", "vi" };
const char * const *match = bsearch(
sig, SIGS, sizeof SIGS / sizeof *SIGS, sizeof *SIGS, cmp);
if(!match) return 0;
va_list args;
va_start(args, retval);
switch(match - SIGS)
{
case 0: { // iii
int a1 = va_arg(args, int);
int a2 = va_arg(args, int);
int rv = ((int (*)(int, int))func)(a1, a2);
if(retval) memcpy(retval, &rv, sizeof rv);
break;
}
case 1: { // v
func();
break;
}
case 2: { // vi
int a1 = va_arg(args, int);
((void (*)(int))func)(a1);
break;
}
default:
assert(!"PANIC");
}
va_end(args);
return 1;
}
// example code:
static int add(int a, int b)
{
return a + b;
}
int main(void)
{
int sum;
dispatch("iii", (void (*)(void))add, &sum, 3, 4);
printf("%i", sum);
return 0;
}
unless you want to mess with assembly thunking (pushing data onto stack before jumping, etc), there is better way other than doing some switch case.
if the destination function is finite and known, why not create a lookup table (map<string, functor>) for it ?
A good implementation of similar ideas is libffi. This implements the gory details of declaring and calling functions with arbitrary calling conventions and signatures. It is (surprisingly) platform portable, and known to work on Linux and Windows out of the box.
An example of its use is the Lua extension library alien. That demonstrates calling arbitrary functions declared at runtime and adapting from native Lua types to the types required for the calling conventions. The specific Lua binding won't be useful to you, but it serves as a complete working example of how and why one might actually use libffi.
Since C has no runtime type information, there is absolutely no need to do a dynamic cast as you are considering. Just pass the pointer and if everything fits, it will work. If the pointer doesn't point to a function with the right signature, there is no way to fix it.
There are basically two solutions:
Go to the assembly level and parse the prototype string there and put the arguments you find in the prototype there where the other function will expect them.
Make a long list of all supported prototypes and compare the current one with the list. When you find a match, you can make the typecast as needed. The most common structure for this test would ba an if-else ladder.
How do I approach a function echo_tpl that can take 1 parameter of type int or string ,and print it out?
C doesn't have templates. I think the best you could do is to use an union or to have the functions have different names. The latter way of having different names is the quasi-standard method of doing it (for instance fabs fabsf fabsl, also heavily used by OpenGL which also accounts for the fact C can't overload functions)
void echo_tpl_s(char const *string) { /* ... */ }
void echo_tpl_i(int number) { /* ... */ }
int main(void) {
echo_tpl_s("Hello world");
echo_tpl_i(42);
}
If there is a lot of common code, you may decide to factor it out in separate functions
void echo_tpl_s(char const *string) {
prepare_output_device();
printf("%s", string);
unprepare_output_device();
}
void echo_tpl_i(int number) {
prepare_output_device();
printf("%d", number);
unprepare_output_device();
}
Or you can take the union way, which will have the function names be equal but instead blow up the parameter type with meta informations.
enum Type {
Number,
String
};
struct Value {
enum Type type;
union {
int number;
char const *string;
} u;
};
void echo_tpl(struct Value value) {
switch(value.type) {
case Number: printf("%d", value.u.number); break;
case String: printf("%s", value.u.string); break;
}
}
int main(void) {
echo_tpl((struct Value) {
.type = String,
.u.string = "Hello world"
});
}
The union way is particular well-suited if you want to store the value somewhere and then execute the print function without caring what value type you pass to it. In C89 you would need to create the value separately since it doesn't have compound literals
int main(void) {
struct Value value;
value.type = String;
value.u.string = "Hello world";
echo_tpl(value);
}
It's a good idea to create functions for that, though
struct Value stringval(char const *string) {
struct Value value;
value.type = String;
value.u.string = string;
return value;
}
struct Value numberval(int number) {
struct Value value;
value.type = Number;
value.u.number = number;
return value;
}
int main(void) {
echo_tpl(stringval("Hello world!"));
}
Some compilers may provide extensions for writing such things. For instance Clang provides function overloading in C.
void echo_tpl(int value) __attribute__((overloadable)) {
printf("%d", value);
}
void echo_tpl(char const *value) __attribute__((overloadable)) {
printf("%s", value);
}
This solves the call-side of the function not to depend on the type. On the definition side, you still have to write the code twice. That's mainly because (as another answer explains) C doesn't have type-generic output functions. Of course if you use this feature, your code becomes nonportable.
The traditional way to translate templates to C is using the preprocessor. I'd do it something like this:
// this creates each template "instance"
#define ECHO_TPL_IMPLEMENT(t) void echo_tpl_##t(t param){\
/* this is where you write your function that uses param */ \
}
// this calls the specific template instance
#define ECHO_TPL(t, val) echo_tpl_##t(val)
// as i wrote it, the function only accepts a 1 word parameter type
// so for simplicity, i'm defining char* to be string
typedef char *string;
// i implement the function for the types int and string
ECHO_TPL_IMPLEMENT(int) // creates echo_tpl_int
ECHO_TPL_IMPLEMENT(string) // creates echo_tpl_string
main()
{
// then i just call them and let the preprocessor handle it
ECHO_TPL(string, "meep"); // will call echo_tpl_string
ECHO_TPL(int, 10); // will call echo_tpl_int
}
This is how the original C++ compilers handled templates, only they had (and still do to this day) more complex type mangling rules, where I just assumed types are 1 word and if they aren't, you'll have to typedef them.
edit: Note that I left the function empty. This is indeed how you write "templated functions" in C, but I cant really write the parameter like you asked because C doesn't have a type-independent file writing api. printf and write require information about the actual type (through the %d or %s and through the length in bytes of what to write respectively), and we don't have that.
Also note that this applies to C++ too. You can't use the C api to write to a file from a template either, you can only really use cout (or the boost format alternative or something similar). You'll have to think what you want to do with the actual function.
Late, but worth adding to this that as of the C11 standard, C now has some very limited support for overloading by using _Generic expressions, that select the right result expression at compile-time based on the type of an input. Nothing like templates but they can answer this old question like this:
#define echo_tpl(X) _Generic((X), int: echo_tpl_i, \
char *: echo_tpl_s)(X)
void echo_tpl_s(char const *string) { /* ... */ }
void echo_tpl_i(int number) { /* ... */ }
int main(void) {
echo_tpl("Hello world");
echo_tpl(42);
}
You still have to define the function implementations using separate names as you would in C99, but you can define a macro with the C++-ish name that inserts a _Generic expression at every point of use, in order to choose the right version for that call site, without making the function user think about the argument type.
It seemingly takes forever for C standards to be fully adopted and I have no idea which compilers implement this feature, but it will become widespread sooner if more people go forth and use it!
template <typename T>
void echo_tpl(const T& t) { std::cout << t; }
EDIT: I didn't spot the c tag. The above answer only works with C++.