1

我有一个带有基于回调的 C API 的 c++ 库。回调类型如下所示:

typedef struct {...} Result;
typedef void (*callback) (const Result* result, void* userData);

用户可以像这样注册一个回调,并可以设置一个指向任意数据的指针,库将通过回调将该指针传回。

我主要关心的是:它是否违反了严格的别名规则?我需要将 userData 的类型更改为 char* 吗?

4

2 回答 2

4

不,别名仅适用于间接指针时,而不是当它们作为指针值传递时。只要用户的行为始终如一,你就会没事的。

也就是说,用户必须确保如果他们传递userData的是实际类型T,那么他们总是T *在访问它之前将其强制转换为回调函数。

我当然假设您没有userData在您的库中进行间接访问,尽管再次将其作为指针访问(例如printf("DEBUG: %p", userData))就可以了。

于 2012-06-12T10:57:24.577 回答
0

您可以为 C 回调 API 创建一个更像“C++”的接口,这可能会消除您的别名问题。

struct Callback {
    void (*callback) (Callback *cb_this, const Result *result);
};

使用 C 回调 API 注册回调的 AC 程序员会执行以下操作:

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.

于 2012-06-12T11:25:27.620 回答