为了提高某些C库代码的类型安全性,我有了在回调函数中使用用户可定义类型的想法。因此,代码不会携带void*
,而是使用Usertype*
。该库仅声明类型,但不定义它,并将此类型用作不透明指针。库定义了所有使用的类型,而不是常规方案,回调函数中使用的部分是前向声明的,并由用户定义。
/*library code*/
struct UserDataForFooCallback; /* opaque user datatype */
typedef void CallbackFn(int i, struct UserDataForFooCallback* user);
void foo(CallbackFn* callback, struct UserDataForFooCallback* user)
{
callback(42, user);
}
/*application code*/
#include <stdio.h>
#include "foo.h"
struct UserDataForFooCallback
{
int a;
};
static void fooCallback(int i, struct UserDataForFooCallback* user)
{
printf(user->a == i ? "ok\n" : "fail\n");
}
int main()
{
struct UserDataForFooCallback cbd = {42};
foo(fooCallback, &cbd);
return 0;
}
优点:
struct MyFoo* data=arg
指针分配缺点:
foo
由不同的程序部分使用)我想知道的主要事情是否真的是一个好主意,或者如果这只是一个看起来好看但却像世界末日一样的想法。
答案 0 :(得分:2)
如果有两个库使用您的库,它们都将UserDataForFooCallback
定义为不同的结构,则它是一个定义规则违规。坚持使用void*
。
答案 1 :(得分:1)
如果您不关心用户数据的类型,则可以始终使用void *。然后人们可以发送他们想要的任何数据。
请注意,这是实现它的C方式。如果您正在使用C ++,则可以创建基类并从中派生。当然,你的回调参数应该是基类。