0

プログラマーが独自のイベントを作成できるイベント システムを作成していますが、イベント データを渡すための void ポインターに問題があります。イベント システムは、おおよそ次のように機能します。

typedef enum { ... USER_EVENT ...} event_type;

typedef struct {
    int id;
    void* data;
} user_event;

typedef struct {
    event_type type;
    union {
        ...
        user_event user;
        ...
    };
} event;

そこで、独自のカスタム構造を使用してユーザー イベントを作成し、それをこの関数に渡します。

void add_user_event(int id, void* data) {
    event e;
    user_event u;
    u.id = id;
    u.data = data;
    e.type = USER_EVENT;
    e.user = u;
    add_event(e); /* add_event is just a function that adds the event to the event stack, and it works fine with predefined events */
}
...
add_user_event(my_user_event_id, (void*)&data);

そして、次のように取得します。

...
if (e.type == USER_EVENT && e.user.id == the_user_id) {
    user_data_struct data = *(user_data_struct*) e.user.data;
    /* do stuff */
}

問題は、これは機能するはずですが、機能しません (完全に文字化けしたデータを提供するだけです)。与えられたデータは問題ない (いくつかのチェックを行った) ことは確かですが、どういうわけか正しいデータを取得できません (ポインターの位置が間違っている可能性がありますか?)。これが役立つ場合、他のいくつかのヒントは、add_user_event呼び出しが関数内で行われることです (イベントは関数内で定義されます)。これは何かに影響しますか?

事前に感謝します。これが十分に明確でない場合はお知らせください。

4

1 に答える 1

1

cnicutarが指摘したように、この問題は void ポインターなどとは関係がなく、単にイベントのデータが関数内に格納されていたためであることが判明しました (関数の実行が終了した後にイベント ハンドラーが呼び出されたため、データはアクセスする前に破棄されます)。

これが私の元のコードでした:

void fire_my_event() {
    my_event_structure ev;
    /* do stuff with ev */
    add_user_event(my_event_id, (void*)&ev);
}
/* ev is now destroyed, before the event handler could be called */

ev次のように「グローバル」にすることで修正しました。

my_event_structure ev;

void fire_my_event() {
    /* reset ev and set values */
    add_user_event(my_event_id, (void*)&ev);
}
/* ev will not be destroyed until the end of the program */
于 2013-02-02T20:45:31.707 に答える