I was having trouble with Ogg Vorbis callbacks not working, specifically the read_func callback, the others all seemed to work. I just made this (in my opinion pointless) change, and suddenly it started working. Does anyone know exactly why, because I am having a hard time seeing the exact difference here. It seems an explicit cast to a function pointer is necessary?
BEFORE (Ogg fails to ever read in valid header data, despite trying):
ov_callbacks oggFileCallbacks;
oggFileCallbacks.read_func = ogg_read_func;
oggFileCallbacks.seek_func = ogg_seek_func;
oggFileCallbacks.tell_func = ogg_tell_func;
oggFileCallbacks.close_func = ogg_close_func;
AFTER (Works perfectly as expected):
ov_callbacks oggFileCallbacks = {
(size_t (*)(void *, size_t, size_t, void *)) ogg_read_func,
(int (*)(void *, ogg_int64_t, int)) ogg_seek_func,
(int (*)(void *)) ogg_close_func,
(long (*)(void *)) ogg_tell_func
};
EDIT: More information
The structure initialization did change when I fixed the problem because it was constructed using the contents in the brackets, but I somehow suspect the real problem was the lack of explicit casting. I thought I had a good knowledge of C++ but I have decided I need to really try to figure out these oddities when I come across them. One thing of note is that my code is in C++, and the Vorbis library is written in plain C. I also decided to force these function pointers to use C prototype declaration style but that did not help the issue either. Structure was initialized like this (for the old way that doesn't work):
ov_callbacks oggFileCallbacks;
Here is the function definition of ogg_read_func:
size_t ogg_read_func(void *ptr, size_t size, size_t nmemb, void *datasource) {
Here are the prototypes:
// Ogg read functions (mainly useful for android (non standard file io ))
extern "C" {
size_t ogg_read_func(void *ptr, size_t size, size_t nmemb, void *datasource);
int ogg_seek_func(void *datasource, ogg_int64_t offset, int whence);
int ogg_close_func(void *datasource);
long ogg_tell_func(void *datasource);
}
The ogg_read_func was just a wrapper to fread when I was debugging the issue, and despite that before changing the structure initialization and doing the cast the error returned was always "Not ogg vorbis", or in code terms this value:
#define OV_ENOTVORBIS -132