带参数的Void*函数

Void* function with a parameter

本文关键字:函数 Void 参数      更新时间:2023-10-16

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

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

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

并通过将数据存储在其中

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

(请注意,上面给出了一个警告"'='无法从'void(__stdcall*)(GLenum)'转换为'void(___cdecl*)(GLenum)")

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

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

现在,我想知道我做错了什么。我在没有参数的情况下工作得很好,但我真的需要参数。

提前感谢

Joey

更改此项:

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

到此:

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

再也不用担心召集大会了。std::function能够存储任何函数或可调用对象,无论其调用约定是什么

不需要铸造:

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

问题是"std::map<std::string, void(*)(GLenum)>中如何存储接受参数的函数指针"?如果是,那么答案是:这是不可能的,因为您声明了一个具有固定函数指针签名的映射。代码中的签名表明,存储的函数指针不接受任何参数。

如果您想存储参数,那么您有两个选项:

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

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

提示:幸运的是,你的程序没有因为错误的调用约定而崩溃。建议将调用约定调整为__cdecl

显然:

void(*)(GLenum)

而不是GLenum函数的正确原型。

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

这样的东西应该可以解决问题:

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

关于什么是调用约定:x86平台上的调用约定