带参数的Void *函数

时间:2015-11-06 19:29:30

标签: c++

对于我尝试编写的应用程序,我需要能够在GLEnable(GL_REPEAT)中编写interface(得到了这个工作)。一旦用户这样做,系统应使用正确的参数调用该函数。

为此,我使用以下变量来获得正确的函数:

std::map<std::string, void(*)(GLenum)> glEnableDisable;

通过以下方式将数据存储在其中:

glEnableDisable["glEnable"]  = glEnable;
glEnableDisable["glDisable"] = glDisable;
  

(请注意,上面给出了警告&#34;&#39; =&#39;无法将&#39; void(__ stdcall *)(GLenum)&#39;转换为&#39; void( __cdecl *)(GLenum)&#39;&#34;)

最后,通过以下方式调用该函数:

((void (*)(GLenum)) Main.glEnableDisable[SplittedUp[0]])(Parameter);

现在,我想知道我做错了什么。我没有参数就能正常工作,但我真的需要参数。

提前致谢,

乔伊

3 个答案:

答案 0 :(得分:2)

改变这个:

std::map<std::string, void(*)(GLenum)> glEnableDisable;

到此:

std::map<std::string, std::function<void(GLenum)>> glEnableDisable;

并且再也不用担心调用约定了。 std::function能够存储任何函数或可调用对象,无论其调用约定如何。

不需要演员:

Main.glEnableDisable[SplittedUp[0]])(Parameter);

答案 1 :(得分:0)

问题是“如何在std::map<std::string, void(*)(GLenum)>中存储一个接受参数的函数指针”?如果是,那么答案是:那是不可能的,因为你声明了一个带有固定函数指针签名的地图。并且代码中的签名是sais,存储的函数指针不接受任何参数。

如果要存储参数,则有两个选项:

  1. 一个包装函数,它访问不在堆栈上的参数,并使用提供的参数调用指定的函数。

  2. 为您正在使用的每个函数指针签名创建一个映射。

  3. 提示:幸运的是,由于错误的调用约定,您的程序没有崩溃。建议将调用约定调整为__cdecl

答案 2 :(得分:0)

显然:

void(*)(GLenum)

GLenum函数的正确原型。

这假定C调用约定,在Visual Studio中默认为__cdecl。但是,您要调用的实际函数使用不同的调用约定,即__stdcall

这样的事情可以解决问题:

typedef void (__stdcall *GLenumFunc)(int, int); // or whatever your params are
//...
std::map<std::string, GLenumFunc> glEnableDisable;

关于调用约定是什么:Calling Conventions on x86 platforms