c++ - COM 中的 C++ 函数指针有问题

标签 c++ com

有一件事困扰着我,C++ 函数指针。我问这个问题是因为我正在尝试实现我的游戏引擎中使用的回调函数。例如,问题是:

// Callback function
HRESULT RenderScene(float fps){ HRESULT hr; return S_OK; }

// Set the message
msk->SetMessage(0, SM_RENDERSCENE, (void*) RenderScene);

问题是 COM 不允许在其成员函数中使用函数指针。此外,不允许多态性。如您所见,我将其设为 void*。没问题,因为我知道回调函数是什么。主要问题是我想要类型安全的东西。 现在说如果用户不知道回调函数声明。例如,

// Callback function
HRESULT CALLBACK RenderScene() or RenderScene(int fps) or RenderScene(int a, int b)

在 WndProc 中实现为:

...
SM_RENDERSCENE:
((void (_stdcall*)(float fps)) pfn)(1.0f);
break;
...

第一个没有参数,因此他看不到 fps。第二,失去精度。第三,失去精度并且有一个未使用的参数。你知道我要去哪里吗?尝试使用 union ,但 COM 不允许在成员函数中使用函数指针。

我试过了,又试了一次。没有任何效果,如果没有这些宏,即使是 MFC 消息映射也是丑陋的。

澄清一下,如果函数不符合 SM_RENDERSCENE 的规范,我宁愿让它返回类似 E_FAILE_INVALIDFUNCTION 的错误。

有没有人能解决这个问题。

注意:我喜欢 COM 规范并且我不会更改,所以请关注问题而不是我为什么使用 COM。谢谢,任何帮助都可以。

最佳答案

HRESULT RenderScene(float fps){ ...}
HRESULT CALLBACK RenderScene() or ...
Is implemented ... ((void (_stdcall*)(float fps)) pfn)(1.0f);

不,COM 肯定支持函数指针。只有当您使用 COM 自动化的子集或需要编码函数调用时,您才会遇到麻烦。这里不是这种情况,您不需要在进程或线程之间编码,也不需要自动化,因为您只使用一种语言。

简单的问题是您遇到了您试图防止的问题,函数指针定义与实现不匹配。是的,(void*) 转换会阻止编译器提示它,在运行时没有任何好事发生。

您的第一个声明有错误的调用约定。使用 STDMETHODIMP 宏是明智的。

你的第二组声明有错误的参数。

第三个代码片段正在应用无效的函数指针转换,转换为返回 void 而不是 HRESULT 的函数。并假设 __stdcall 即使您的 RenderScene() 函数没有使用 STDMETHODIMP 或 CALLBACK。这就是您看不到参数的正确值的原因。

通过声明指针类型的别名来解决函数指针问题:

 typedef HRESULT (__stdcall * RenderSceneCallback)(float fps);

并在所有声明中始终使用 RenderSceneCallback。从不转换。

关于c++ - COM 中的 C++ 函数指针有问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8373429/

相关文章:

c++ - 什么时候在 C/C++ 中分配静态内存?在编译时还是在程序运行的最开始?

c++ - 简单的 I/O 操纵器未按预期工作

java - 使用 JRE 7 或 JRE 8 创建 dll 的过程

internet-explorer - 在Powershell中使用IE COM对象自动从Web保存文件

c++ - 成员方法如何删除对象?

c++ - COM 代码库位置 - 如何选择要使用的版本?

c++ - boost 。方便的 variables_map。利用在 options_desctription 中指定的类型

c++ - 如何在 C++ 中创建一个长度等于用户输入的数组?

c++ - 自定义迭代器

c++ - ATL/COM:为什么 CComSafeArray::GetCount() 会为空数组引发异常?