手动调用OpenGL函数

时间:2016-07-30 12:52:16

标签: c++ opengl gcc glx

我一直致力于创建一个OpenGL函数加载库,它可以帮助我在需要时调用OpenGL函数。

我有一个使用glX的getProcAddress函数。

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

    return pr;
}

返回OpenGL函数的地址。如果我不使用reinterpret_cast s,那么我会遇到奇怪的编译错误,这就是为什么他们会在那里。

然后我在头文件中定义了一个gl *函数原型:

typedef void _GLACTIVETEXTURE(GLenum texture);

其中GLenum在另一个头文件中定义为枚举。然后我在类中声明函数指针:

_GLACTIVETEXTURE glActiveTexture;

然后在名为init的函数中执行:

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

getProcAddress函数自行编译很好,但上面的代码行不会编译。 GCC抛出此编译器错误:

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

而且我不知道如何处理这种编译器错误。它没有任何意义,因为这是一个函数指针,而不是函数本身,除非我使用()。我不确定这里的问题是什么;无论是来自我方还是海湾合作委员会。目前尚不清楚。我试图摆弄指针和空洞,但都是徒劳的,同样的错误信息出现了。有谁知道这里发生了什么,以及如何正确调用OpenGL函数?

2 个答案:

答案 0 :(得分:4)

@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 *类型的对象可以保存指向a的指针   功能。将指针转换为函数的结果   指向另一种数据类型(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的rvalue。

答案 1 :(得分:3)

您的typedef错了。您正在为函数类型创建别名,而不是函数指针。这是正确的做法:

typedef void (*_GLACTIVETEXTURE)(GLenum texture);