我知道有很多关于将void *强制转换为struct的问题,但我无法设法使其正确运行。

好吧,我想创建一个线程来在后台播放音乐。我有一个结构,可以收集加载的音乐文件数组以及开始和结束索引:

typedef unsigned char SoundID;
typedef unsigned char SongID;

typedef struct {
    Mix_Music *songs[9]; // array of songs
    SongID startId;      // index of first song to play
    SongID endId;        // index of last song to play
} SongThreadItem;

然后,我想通过创建线程并将实际播放歌曲的函数传递给thread_create()函数来播放歌曲。
int play_songs(Mix_Music *songs[9], SongID startId, SongID endId, char loop){
    thrd_t thrd;
    SongThreadItem _item;
    SongThreadItem *item = &_item;

    memcpy(item->songs, songs, sizeof(item->songs));
    item->startId = startId;
    item->endId = endId;
    printf("item->startId is %i\n", item->startId);
    printf("item->endId is %i\n", item->endId);
    thrd_create_EC(thrd_create(&thrd, audio_thread_run, item));

    return 0;
}

int audio_thread_run(void *arg){
    SongThreadItem *item = arg; // also tried with = (SongThreadItem *)arg

    printf("item->startId is %i\n", item->startId);
    printf("item->endId is %i\n", item->endId);
    free(item);

    return 0;
}

然后我得到以下输出:
item->startId is 0
item->endId is 8
item->startId is 6
item->endId is 163

audio_thread_run()中检索到的值不是预期的值。我不知道我是否放置了足够的代码来让别人发现我的错误,我试图将其最小化,因为它是更大项目的一部分。

在此先感谢您的帮助。

最佳答案

该线程异步运行,但是您要向其传递指向调用play_songs()的线程堆栈上的SongThreadItem的指针。

如果只有一个调用play_songs()的线程,并且只有在完成item之后才再次调用它,则可以这样定义_item:

static SongThreadItem _item;

这样它就位于数据段中并且不会被覆盖。

如果您不知道何时和谁将调用play_songs(),则只需在完成后在线程中将malloc_item进行free即可:
...
SongThreadItem *item = (SongThreadItem *)malloc(sizeof(SongThreadItem));
...

后者通常是更好的主意。可以将其视为将数据的所有权传递给新线程。当然,如果线程创建失败,则生产质量代码应释放该项目。

关于c - C-在thrd_create()中将void *转换为结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28831434/

10-11 19:16