【问题标题】:Creating a map of __stdcall创建 __stdcall 的映射
【发布时间】:2012-06-22 20:58:00
【问题描述】:

我正在尝试使用 __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,如果这令人困惑的话。

【问题讨论】:

标签: c++ types function-pointers stdcall


【解决方案1】:

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

map<string, InitializeDLL> mapInt;

我不知道你为什么首先尝试做其他事情,因为你已经在其他地方使用过这种类型,难道这里也需要它吗?

【讨论】:

  • 那么,使用 InitializeDLL 进行映射是没有意义的,因为那样我就需要为每个函数创建一个映射,并首先破坏使用映射的目的。我认为 __stdcall 是获取函数指针的某种方式,但正如在聊天中向我解释的那样,这与尝试将 'const' 之类的东西作为类型传递没有什么不同。
  • @Atlos:即使您可以使用__stdcall 作为类型,它如何让您比void* 更接近?您仍然需要更多信息才能实际使用指针。
【解决方案2】:

函数指针类型不限于单个函数。例如,您的 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 更有帮助。

如果您向我们展示您打算如何在地图中调用回调函数(包括函数签名不同的情况),我也许可以向您展示如何使用 functionbind 为您的用例。


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

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

【讨论】:

  • 这更符合我的想法,但对于不同的返回类型和参数配置,我仍然会得到很多 CallbackFunction 的变体。没有通用的方法可以指向我制作的任何 CALLBACK* typedef?
  • 为了节省时间,我不得不手动将每个函数名称字符串与已知函数列表进行比较,然后选择适当的命令。下次我会尝试更“优雅”的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-08
  • 1970-01-01
  • 2012-03-07
  • 2018-07-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多