我想为c函数创建一个包装器,以便我可以将ret = function(arg1,arg2,arg3);
形式的函数调用转换为/*void*/ function_wrapper(/*void*/);
形式。这类似于C ++和boost bind中的函数对象。
这可能吗?我怎么能这样做?
更新
更详细地解释我在寻找什么:
我们从这个功能开始:
int f(int i){
//do stuff
return somevalue;
}
Obvioulsy,它被称为:
// do stuff
int x = 0;
ret = f(0);
// do more stuff.
我想做一些将函数包装到void function(void)
struct function_object fo;
fo.function_pointer = &f;
fo.add_arg(x, int);
fo.set_ret_pointer(&ret);
fo.call();
注意:我看到有人投票支持关闭这个问题并将其标记为不清楚。请不要这样做。我有合理的需要来回答这个问题。如果您需要解释,请询问,我很乐意详细说明。
答案 0 :(得分:1)
我想出了一个更好的代码,可以让你做你想做的事。首先,我将解释它是如何工作的,展示代码并解释为什么我仍然不认为使用它是个好主意(尽管代码可能为解决这些问题的改进打开了大门)。
FUNCTIONOBJ_initialize();
),它将初始化库中使用的每个数据结构的互斥锁。FUNCTIONOBJ_handler_t
指针并调用get_function_handler()
来完成的。这将搜索目前可以使用的免费FUNCTIONOBJ_handler
数据结构。FUNCTIONOBJ_handler
数据结构都很忙,则会被某些函数调用使用)NULL
将被返回。get_function_handler()
找到了FUNCTIONOBJ_handler
数据结构,它会尝试锁定FUNCTIONOBJ_id_holder
数据结构,该数据结构包含ID
的{{1}}功能即将被召唤。FUNCTIONOBJ_handler
已被锁定,FUNCTIONOBJ_id_holder
将会挂起,直到线程使用它解锁。get_function_handler()
后,会在其上写入抓取的FUNCTIONOBJ_id_holder
的ID,FUNCTIONOBJ_handler
会返回FUNCTIONOBJ_handler
指针。get_function_handler
和set_args_pointer
的返回变量,它们都以set_return_pointer
作为参数。最后,您可以调用所需的功能。它必须:
1 - 从void *
数据结构中抓取FUNCTIONOBJ_handler
ID
并使用它来获取指向FUNCTIONOBJ_id_holder
本身的指针。
2 - 使用FUNCTIONOBJ_handler
访问参数。
3 - 使用返回函数之一返回(在示例中我们有FUNCTIONOBJ_handler
,它将返回一个整数并解锁ret_int
)
下面是一个简化的思维导图,描述了一些正在发生的事情:
最后,代码:
<强> funcobj.h 强>:
FUNCTIONOBJ_handler
<强> funcobj.c 强>:
#include <stdio.h>
#include <pthread.h>
#define MAX_SIMULTANEOUS_CALLS 1024
typedef struct {
//Current ID about to be called
int current_id;
//Mutex
pthread_mutex_t id_holder_mutex;
} FUNCTIONOBJ_id_holder_t;
typedef struct {
//Attributes
void *arguments;
void *return_pointer;
//Mutex
pthread_mutex_t handler_mutex;
} FUNCTIONOBJ_handler_t;
FUNCTIONOBJ_handler_t FUNCTIONOBJ_handler[MAX_SIMULTANEOUS_CALLS];
FUNCTIONOBJ_id_holder_t FUNCTIONOBJ_id_holder;
void set_return_pointer(FUNCTIONOBJ_handler_t *this, void *pointer);
void set_args_pointer(FUNCTIONOBJ_handler_t *this, void *pointer);
void ret_int(FUNCTIONOBJ_handler_t *this, int return_value);
void FUNCTIONOBJ_initialize(void);
FUNCTIONOBJ_handler_t *get_function_handler(void);
<强>的main.c 强>:
#include "funcobj.h"
void set_return_pointer(FUNCTIONOBJ_handler_t *this, void *pointer){
this->return_pointer = pointer;
}
void set_args_pointer(FUNCTIONOBJ_handler_t *this, void *pointer){
this->arguments = pointer;
}
void ret_int(FUNCTIONOBJ_handler_t *this, int return_value){
if(this->return_pointer){
*((int *) (this->return_pointer)) = return_value;
}
pthread_mutex_unlock(&(this->handler_mutex));
}
void FUNCTIONOBJ_initialize(void){
for(int i = 0; i < MAX_SIMULTANEOUS_CALLS; ++i){
pthread_mutex_init(&FUNCTIONOBJ_handler[i].handler_mutex, NULL);
}
pthread_mutex_init(&FUNCTIONOBJ_id_holder.id_holder_mutex, NULL);
}
FUNCTIONOBJ_handler_t *get_function_handler(void){
int i = 0;
while((0 != pthread_mutex_trylock(&FUNCTIONOBJ_handler[i].handler_mutex)) && (i < MAX_SIMULTANEOUS_CALLS)){
++i;
}
if(i >= MAX_SIMULTANEOUS_CALLS){
return NULL;
}
//Sets the ID holder to hold this ID until the function is called
pthread_mutex_lock(&FUNCTIONOBJ_id_holder.id_holder_mutex);
FUNCTIONOBJ_id_holder.current_id = i;
return &FUNCTIONOBJ_handler[i];
}
编译:{{1}}
#include "funcobj.h"
#include <string.h>
//Function:
void print(void){
//First the function must grab the handler that contains all its attributes:
//The FUNCTIONOBJ_id_holder is mutex locked, so we can just access its value and
//then free the lock:
FUNCTIONOBJ_handler_t *this = &FUNCTIONOBJ_handler[FUNCTIONOBJ_id_holder.current_id];
//We dont need the id_holder anymore, free it!
pthread_mutex_unlock(&FUNCTIONOBJ_id_holder.id_holder_mutex);
//Do whatever the function has to do
printf("%s\n", (char *) this->arguments);
//Return the value to the pointed variable using the function that returns an int
ret_int(this, 0);
}
void *thread_entry_point(void *data){
int id = (int) data;
char string[100];
snprintf(string, 100, "Thread %u", id);
int return_val;
FUNCTIONOBJ_handler_t *this;
for(int i = 0; i < 200; ++i){
do {
this = get_function_handler();
} while(NULL == this);
set_args_pointer(this, string);
set_return_pointer(this, &return_val);
print();
}
return NULL;
}
int main(int argc, char **argv){
//Initialize global data strucutres (set up mutexes)
FUNCTIONOBJ_initialize();
//testing with 20 threads
pthread_t thread_id[20];
for(int i = 0; i < 20; ++i){
pthread_create(&thread_id[i], NULL, &thread_entry_point, (void *) i);
}
for(int i = 0; i < 20; ++i){
pthread_join(thread_id[i], NULL);
}
return 0;
}
结构,解锁gcc -o program main.c funcobj.c -lpthread
结构,通过你抓住并使用非内置函数返回值的指针)。如果不小心,这会大大增加错误的机会,特别是一些令人讨厌的错误:FUNCTIONOBJ_handler
结构,程序将会死锁。