Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 手动调用OpenGL函数_C++_Opengl_Gcc_Glx - Fatal编程技术网

C++ 手动调用OpenGL函数

C++ 手动调用OpenGL函数,c++,opengl,gcc,glx,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))); retur

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

我有一个使用glX的
getProcAddress
函数

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

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

_GLACTIVETEXTURE glActiveTexture;
然后在一个名为
init
I的函数中:

void GLFunctions::init()
{
    glActiveTexture = (_GLACTIVETEXTURE)getProcAddress("glActiveTexture");
}
getProcAddress
函数本身可以很好地编译,但是上面的代码行不会编译。GCC抛出此编译器错误:

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

我不知道如何处理这种编译器错误。这毫无意义,因为这是一个函数指针,而不是函数本身,除非我使用
()
。我真的不确定这里的问题是什么;不管是我这边还是GCC。不清楚。我试过摆弄指针和空洞,但都是徒劳的,同样的错误信息出现了。有人知道这里发生了什么,以及我如何正确调用OpenGL函数吗?

您的
typedef
是错误的。您正在创建函数类型的别名,而不是函数指针的别名。这是如何正确完成的:

typedef void (*_GLACTIVETEXTURE)(GLenum texture);

@nshct已经向您解释了为什么编译器会抱怨您的代码。这个答案没有提到的是,为什么你的
重新解释演员阵容
首先是必要的。原因是,函数指针与常规指针不同,完全可能是
sizeof(void*)!=sizeof(void(*)(void))
,即函数指针的值范围和对齐规则可能与常规指针完全不同。
dlsym
的手册页详细说明了这一点:

根本原因 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
的定义知道这一点,并且已明确编写,以便返回函数指针。但由于函数指针不同于常规指针,所以不能将函数指针强制转换为常规指针。相反,您必须强制转换为目标函数指针类型,或强制转换赋值中的函数指针变量左值(与dlsym一样),以匹配glXGetProcAddress的右值。

我希望您知道glew@他想手动加载函数指针。@Akib Azmain不要居高临下。指出替代解决方案并可能为某人节省大量工作不是犯罪。有没有真正的系统函数指针和常规指针实际上是不同的?我并不怀疑这个理论,只是想知道这是否是一个现实生活中的问题。@RetoKoradi:几乎每一个哈佛架构处理器。大多数DSP是哈佛体系结构,许多µC也是。@RetoKoradi:例如,看看模拟设备ADSP-219x DSP:它们使用16位可寻址数据内存总线(即16位数据地址空间),但程序内存总线有24位可寻址位(24位地址空间)。因此,如果将函数指针强制转换为常规数据指针,它将被截断。具有dlsym[posix/unix]或GetProcAddress[Windows]的系统必然具有统一的数据和代码指针。对于其他系统,没有这样的说法。此外,我认为如果数据指针和代码指针的大小不同,这种“左值转换技巧”会导致问题(例如:如果数据指针长32位,代码指针长16位,那么在“fptr”之后写16位)
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");