2014-12-15 6 views
5

Ich habe diese Funktion:Wie in Funktion Argument eine Zeigerfunktion übergeben mit Wrapper-Funktion?

void boot(uint ncores, uint nterm, Task boot_task, int argl, void* args) 
{ 

for(int i=0; i<MAX_PROC;i++) { 
    PT[i].ppid = NOPROC; 
} 
nextproc = 0; 

curproc = NOPROC; 
Exec(boot_task, argl, args); 
} 

und und ich möchte stattdessen Exec() der Verwendung pthread zu verwenden, so dass ich die cpu_boot nennen:

void cpu_boot(uint cores, interrupt_handler bootfunc, uint serialno) 
{ 
//I cannot change this function 
} 

Das sind die Typen der Argumente sind

typedef void interrupt_handler(); 
typedef int (* Task)(int, void*); 

ich habe versucht:

void boot(uint ncores, uint nterm, Task boot_task, int argl, void* args) 
{ 
    void my_wrapper() 
    { 

     int y; 
     y= boot_task(argl, args); 
    } 

    cpu_boot(ncores, my_wrapper , nterm); 
} 

Aber das ist falsch. Wie kann ich das umsetzen?

+0

Da die beiden Variablen: PT [] und nextproc nicht definiert sind (sind das globale Variablen?) Gibt es ein paar andere Probleme: 1) kann keine nächsten Funktionen in C 2) die typedef-Anweisungen benötigen einen 'trailing'-Namen Verwenden Sie, um das Typedef zu verweisen. 3) das: typedef void interrupt_handler(); ist kein gültiger Prototyp für eine Interrupt-Funktion. das ist: typedef void interrupt_handler (void); als Interrupt-Funktionen können in Parametern nicht übergeben worden sein, da sie nie aufgerufen werden. – user3629249

+0

@ user3629249: Die beiden Typedefs sind 'OK'; Die Namen der Typedefs sind 'interrupt_handler' und' Task'. Die Definition von "interrupt_handler" sollte die akzeptablen Argumente angeben oder "void" angeben, wenn die Funktion keine Argumente annimmt, aber das ist ein (relativ) kleines Problem. Beachten Sie, dass Standardsignal-Handler im User-Space, in denen Pthreads normalerweise verwendet werden, den Typ "void (* handler) (int signum) haben;" - die Funktion benötigt ein Argument. Signalhandler und Interrupthandler werden aufgerufen; sie wären sinnlos, wenn sie nie angerufen würden. –

Antwort

2

Sie werden so etwas wie dies wollen:

void some_interrupt_handler(){ 
    /* code here */ 
    return; 
} 

interrupt_handler* my_wrapper(Task boot_task, int argl, void* args) 
{ 
    /* 
     this is where you run boot task 
    */ 
    boot_task(argl, args); 

    /* then pick an interrupt_handler to return... */ 
    void (*function_ptr)() = some_interrupt_handler; 

    return function_ptr; 
} 

Dann können Sie Ihre Wrapper wie folgt verwenden:

void boot(uint ncores, uint nterm, Task boot_task, int argl, void* args) 
{ 
    cpu_boot(ncores, my_wrapper(boot_task, argl, args) , nterm); 
} 
+0

Wie kann ich im Argument bootfunc die Bezeichnung einer Wrapper-Funktion übergeben, ohne sie aufzurufen? So etwas wie cpu_boot (ncores, my_wrapper, nterm); @Grzegorz Szpetkowski –

+0

@Lefteris Sarantaris: Sie könnten den Funktionszeiger als weiteren Parameter von my_wrapper übergeben. Sie können 'cpu_boot (ncores, my_wrapper, nterm) 'nicht verwenden, es sei denn' my_wrapper' ist vom Typ interrupt_handler - in diesem Fall haben Sie keine Möglichkeit Argumente (argl, args etc) an sie zu übergeben, da interrupt_handler dies nicht tut nimm Argumente ... Ich denke, der nächste, den du bekommen kannst, ist 'my_wrapper (boot_task, boot_func, argl, args)', wobei boot_func ein Funktionszeiger ist. –

1

Ein allgemeineres und vieles mehr flexable Art und Weise ...

void some_interrupt_handler(){ 
    /* code here */ 
    return; 
} 

typdef struct boot_data_struct { 
    int argc; 
    void * argv; 
    Task boot_task; 
    interrupt_handler * handler; 
} boot_data; 

interrupt_handler* my_wrapper(void * data) 
{ 
    boot_data * bootData = data; 

    /* 
     this is where you run boot task 
    */ 
    data->boot_task(bootData->argc, bootData->argv); 

    return bootData->handler; 
} 

Dann können Sie Ihre Verpackung wie folgt verwenden:

void boot(uint ncores, uint nterm, Task boot_task, int argl, void* args) 
{ 
    boot_data * data = malloc(sizeof *data); 
    //remember to memset if you arent going to fill out all variables! 
    data->argc = argl; 
    data->argv = args; 
    data->boot_task = boot_task; 
    data->handler = some_interrupt_handler; 

    cpu_boot(ncores, my_wrapper(data) , nterm); 

    free(data); 
}