对于我尝试编写的应用程序,我需要能够在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);
现在,我想知道我做错了什么。我没有参数就能正常工作,但我真的需要参数。
提前致谢,
乔伊
答案 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,存储的函数指针不接受任何参数。
如果要存储参数,则有两个选项:
一个包装函数,它访问不在堆栈上的参数,并使用提供的参数调用指定的函数。
为您正在使用的每个函数指针签名创建一个映射。
提示:幸运的是,由于错误的调用约定,您的程序没有崩溃。建议将调用约定调整为__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