简体   繁体   中英

How do I bind arguments to a C function pointer?

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));
}

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();
}


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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM