1

コールバックベースのCAPIを備えた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 に答える