我正在使用高度异步的C项目。不幸的是,很快就会发现有很多样板文件的形式是指定包含回调用户数据的结构。
例如:
typedef struct SomeUserData {
int foo;
int bar;
} SomeUserData;
void someCallback(void * userData)
{
SomeUserData * myData = userData;
// ...
free(myData);
}
void someFunc(void)
{
SomeUserData * myData = calloc(1, sizeof(*myData));
myData->foo = 5;
myData->bar = 10;
doSomeAsync(someCallback, myData);
}
当只有一两个回调时,情况并非如此糟糕,但由于涉及的异步步骤数量很多,我现在正在处理的项目部分有数百个。
我喜欢的东西类似于C ++中的bind
。有没有办法用一些C宏技巧实现类似的结果,甚至在运行时使用可变参数获得某些东西?
答案 0 :(得分:1)
C宏技巧并不总是最容易调试,但是:
#include <stdlib.h>
typedef struct Type1 {
int foo ;
} Type1 ;
typedef struct Type2 {
char* bar ;
} Type2 ;
#define CALLBACK( Type ) \
void my##Type##Callback( Type* myData ) ; \
void Type##Callback( void* userData ) \
{ \
my##Type##Callback( (Type*) userData ) ; \
free( userData ) ; \
} \
void my##Type##Callback( Type* myData )
CALLBACK( Type1 )
{
printf( "Type1=%d\n", myData->foo ) ;
}
CALLBACK( Type2 )
{
printf( "Type2=%s\n", myData->bar ) ;
}
void doAsync( void (*callback)( void* ), void* data )
{
(*callback)( data ) ;
}
int main()
{
Type1* t1 = calloc( 1, sizeof(*t1) ) ;
Type2* t2 = calloc( 1, sizeof(*t2) ) ;
t1->foo = 42 ;
t2->bar = "TheAnswer" ;
doAsync( myType1Callback, t1 ) ;
doAsync( myType2Callback, t2 ) ;
}
可能有所帮助。它声明一个“myXXXCallback”获取指向指定类型的指针,然后创建一个“XXXCallback”,取一个void *调用特定于类型的版本,然后释放数据。 “技巧”是使用“##”运算符将传入的类型连接到函数名称中。