Вызов функций OpenGL вручную

Я работал над созданием библиотеки загрузки функций OpenGL, которая поможет мне вызывать функции OpenGL, когда они мне понадобятся.

у меня есть getProcAddress функция, которая использует glX.

void* getProcAddress(const char *name)
{
auto pr = reinterpret_cast<void*>(glXGetProcAddress(
reinterpret_cast<const unsigned char*>(name)));

return pr;
}

Это возвращает адрес функции OpenGL. Я получаю странные ошибки компилятора, если я не использую reinterpret_castТак вот почему они там.

Затем я определяю прототип функции gl * в заголовочном файле:

typedef void _GLACTIVETEXTURE(GLenum texture);

куда GLenum определяется в другом заголовочном файле как enum. Затем я объявляю указатель на функцию в классе:

_GLACTIVETEXTURE glActiveTexture;

А затем в функции под названием init Я делаю:

void GLFunctions::init()
{
glActiveTexture = (_GLACTIVETEXTURE)getProcAddress("glActiveTexture");
}

getProcAddress Функция компилируется сама по себе, но приведенная выше строка кода не скомпилируется. GCC выдает эту ошибку компилятора:

error: invalid cast to function type ‘_GLACTIVETEXTURE {aka void(GLenum)}’

И я не знаю, как бороться с такой ошибкой компилятора. Это не имеет смысла, потому что это указатель на функцию, а не сама функция, если я не использую (), Я не совсем уверен, в чем здесь проблема; будь то с моей стороны или GCC. Не ясно. Я попытался поиграться с указателями и пустотами, но все напрасно, и появляется то же самое сообщение об ошибке. Кто-нибудь знает, что здесь происходит и как я могу правильно вызывать функции OpenGL?

2

Решение

Ваш typedef неправильно. Вы создаете псевдоним для функции тип, не для функции указатель. Вот как это делается правильно:

typedef void (*_GLACTIVETEXTURE)(GLenum texture);
3

Другие решения

@nshct уже дал вам объяснение, почему компиляторы жалуются на ваш код. Что этот ответ не адресовал, почему ваш reinterpret_cast было необходимо в первую очередь. Причина в том, что указатели на функции отличаются от обычных указателей, и вполне возможно, что sizeof(void*) != sizeof(void(*)(void))то есть указатели на функции могут иметь совершенно иной диапазон значений и правил выравнивания, чем обычные указатели. Справочная страница для dlsym адрес это подробно:

http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html

обоснование

Стандарт ISO C не требует, чтобы указатели на функции могли быть
бросать взад и вперед к указателям на данные. Действительно, стандарт ISO C
не требует, чтобы объект типа void * может содержать указатель на
функция. Реализации, поддерживающие расширение XSI, однако, делают
требуют, чтобы объект типа void * может содержать указатель на
функция. Результат преобразования указателя на функцию в
указатель на другой тип данных (кроме void *) все еще не определено,
тем не мение. Обратите внимание, что компиляторы, соответствующие стандарту ISO C,
требуется для создания предупреждения, если преобразование из void * указатель
на указатель на функцию делается так:

fptr = (int (*)(int))dlsym(handle, "my_function");

Из-за проблемы, отмеченной здесь, будущая версия может либо добавить новую
функция для возврата указателей на функции, или текущий интерфейс может быть
устарел в пользу двух новых функций: одна возвращает данные
указатели и другие, которые возвращают указатели на функции.

Из-за этого при использовании dlsym необходимо использовать особый способ кастинга, а именно некоторую хитрость литья.

void    *handle;
int     (*fptr)(int);

/* open the needed object */
handle = dlopen("/usr/home/me/libfoo.so", RTLD_LOCAL | RTLD_LAZY);

/* find the address of function and data objects */
*(void **)(&fptr) = dlsym(handle, "my_function");

Определение glXGetProcAddress знает об этом и был явно написан так, что он возвращает указатель на функцию. Но поскольку указатели на функции отличаются от обычных указателей, вы не должны преобразовывать указатель на функцию в обычный указатель. Вместо этого вы должны привести либо к типу указателя целевой функции, либо привести переменную указателя функции lvalue в присваивании (как в случае с dlsym), чтобы соответствовать значению glXGetProcAddress.

4

По вопросам рекламы [email protected]