我有一个带有基于回调的C API的c ++库。回调类型如下所示:
typedef struct {...} Result;
typedef void (*callback) (const Result* result, void* userData);
用户可以注册这样的回调,并可以设置指向任意数据的指针,并且库将通过回调传递该指针。
我主要担心的是: 是否违反了严格的别名规则?我是否需要将userData的类型更改为char *?
答案 0 :(得分:4)
不,别名仅在指针间接指示时适用,而不是在指针作为指针值传递时。只要用户表现得一致,你就可以了。
也就是说,用户必须确保如果他们通过userData
实际类型T
,那么他们总是在访问回调函数之前将其转换为T *
。
我当然假设你没有在你的图书馆中间接userData
,尽管再次将其作为指针访问(例如printf("DEBUG: %p", userData)
)也没问题。
答案 1 :(得分:0)
您可以为C回调API创建更多“C ++” - ish界面,这可能会消除您的别名问题。
struct Callback {
void (*callback) (Callback *cb_this, const Result *result);
};
使用C回调API注册回调的C程序员可以这样做:
struct MyCallback {
struct Callback cb;
int x;
double y;
/* ... */
};
void my_callback_func (Callback *cb_this, const Result *result) {
MyCallback *my_cb = (MyCallback *)cb_this;
/* ... */
}
MyCallback mycb = { { my_callback_func }, 0, 0, /* ... */ };
这样您就不必担心处理void *
了。而是通过单个指针传递给Callback
。