创建__stdcall的映射

时间:2012-06-20 16:51:13

标签: c++ types function-pointers stdcall

我正在尝试使用__stdcall创建函数名称和函数指针的映射。以下是我目前获取函数指针的方法:

typedef int (CALLBACK* InitializeDLL)(int,int);
InitializeDLL initializeDLL = (InitializeDLL)GetProcAddress(hInstanceLibrary, "InitializeDLL");

现在我的地图:

map<string, int *__stdcall> mapInt;
mapInt["InitializeDLL"] = initializeDLL; //throws error for "InitializeDLL cannot be assigned to entity of type int*"

这个错误正是我的预期,但我需要在__stdcall前面添加一个类型。如果我删除前面的“int”,它会抱怨:

Error: expected a type specifier

如果我在仅创建前面包含“int”的地图对象后尝试编译它,则会抛出错误:

error C2059: syntax error : '>'

这对我来说没什么意义。那么将__stdcall用作地图类型的正确方法是什么?在我面前添加int似乎对我很怀疑,但如果我不添加它,那么它会抱怨它需要指定的类型。

此外,如果令人困惑,CALLBACK是__stdcall的#define。

2 个答案:

答案 0 :(得分:4)

您正在使用类似的__stdcall,但它不是一个。您需要在地图定义中使用函数指针类型。

map<string, InitializeDLL> mapInt;

我不确定你为什么一开始就尝试做其他事情,因为你已经在其他地方使用过这种类型了,难道不是很明显这里也需要它吗?

答案 1 :(得分:3)

函数指针类型不限于单个函数。例如,您的InitializeDLL函数指针类型可以包含指向具有此签名的任何函数的指针:int foo(int,int)

或许CallbackFunction对于该typedef来说是一个更好的名称,因为它包含所有具有可用于回调的签名的函数:

typedef int (CALLBACK* CallbackFunction)(int,int);
CallbackFunction initializeDLL =
    (InitializeDLL)GetProcAddress(hInstanceLibrary, "InitializeDLL");
map<string, CallbackFunction> mapInt;
mapInt["InitializeDLL"] = initializeDLL;

有更多通用的方法来处理函数(甚至是成员函数)。如果您有能力/愿意使用新的C ++ 11功能,则可以使用std::functionstd::bind。如果没有,那么您可以使用boost::functionboost::bind。这些工具的Boost和C ++ 11版本以完全相同的方式使用。 Boost文档比cppreference更有用。

如果您向我们展示您打算如何调用地图中的回调函数(包括函数签名不同的情况),我可能会向您展示如何使用function和{{1对于你的用例。


您可能会考虑让所有命令回调具有相同的函数签名,然后让每个回调负责提取他们完成工作所需的任何参数。包含命令参数的对象可以作为参数传递给回调函数。

您还可以考虑以std::vector<boost::any>std::vector<boost::variant>的形式将参数列表传递给回调函数。然后,回调函数将每个bindboost::any转换为与该特定参数关联的特定类型。如果命令参数类型是简单的内置类型,您甚至可以使用boost::variant,其中std:vector<UnionOfPossibleParameterTypes>是一个普通的旧C风格UnionOfPossibleParameterTypes