将函数指针实现替换为std :: function,以便在PlayFab SDK中使用lambda

键盘

我目前正在尝试将PlayFab C ++ SDK包含到我的应用程序中。该SDK主要用于游戏引擎Cocos2d-x,但基本上可以用于任何C ++应用程序。

它只是普通的REST,因此您将请求发送到它们的服务器并等待响应。这对于使用lambdas是完美的。

他们声明此回调,当请求成功时将调用该回调:

template<typename ResType> using ProcessApiCallback = void(*)(const ResType& result, void* userData);

不幸的是,他们没有使用std :: function,而是一个函数指针。这样一来,便无法使用捕获变量的lambda。

因此,我以为我可以简单地用std :: function回调替换此函数指针回调,如下所示:

template<typename ResType> using ProcessApiCallback = std::function<void(const ResType& result, void* userData)>;

不幸的是,事情并非如此简单,因为它们使用丑陋的reinterpret_casts存储了函数指针,下面是一个示例(删除不必要的部分以使其简短):

void PlayFabClientAPI::LoginWithAndroidDeviceID(
    LoginWithAndroidDeviceIDRequest& request,
    ProcessApiCallback<LoginResult> callback,
    ErrorCallback errorCallback,
    void* userData
    )
{
    // here they assign the callback to the httpRequest
    httpRequest->SetResultCallback(reinterpret_cast<void*>(callback));
    httpRequest->SetErrorCallback(errorCallback);
    httpRequest->SetUserData(userData);

    PlayFabSettings::httpRequester->AddRequest(httpRequest, OnLoginWithAndroidDeviceIDResult, userData);
}

稍后,当请求成功时,他们将执行以下操作:

if (request->GetResultCallback() != nullptr)
{
    ProcessApiCallback<LoginResult> successCallback = reinterpret_cast<ProcessApiCallback<LoginResult>>(request->GetResultCallback());
    successCallback(outResult, request->GetUserData());
}

HttpRequest类具有以下字段:

void* mResultCallback;

问题是我不知道如何在HttpRequest类中存储任意std :: function指针,然后再将其返回。我尝试了很多事情,包括非常丑陋的reinterpret_casting,但没有任何效果。

我愿意对他们的SDK进行任何更改。我也将此报告为不良设计,他们同意,但是他们没有时间对其进行改进,但是如果可以找到好的解决方案,他们将接受拉取请求。

山姆·瓦尔沙夫奇克(Sam Varshavchik)

此处的关键信息是userData指针。它作为请求的一部分提供,并被传递回您的回调函数。这是一个不透明的指针,库不关注它,否则,除了将其转发到您的回调外。

这就是您将在这里使用的。

这是使用C编写的面向服务的通用库的一种非常常见的设计模式。它们的API通常以这种方式构造:它们接受带有额外不透明指针的请求。他们存储该指针,并在请求完成时将其传递回用户提供的回调。

然后,回调将其用于将任何种类的其他元数据与请求相关联。

这是一个C ++库,但是他们选择为库回调实现C风格的设计模式。那真不幸。

但是,无论如何,在您的情况下,您将动态分配std::function或包含您的的某个类的实例std::function以及所需的任何其他数据,并将指向动态分配结构的指针传递给请求。

当您的回调被调用时,它只需要reinterpret_cast指向动态分配类型的不透明指针,复制它的内容delete(当然,以避免内存泄漏),然后继续将复制的内容用作回调操作的一部分(是否涉及调用std::function或其他无关紧要的信息)。

由于这是您正在使用的C ++库,而不是C库,因此不幸的是,他们选择实现此C风格的不透明指针传递设计模式。当然,有更好的方法可以用C ++实现,但这是您必须使用的方法,因此您必须处理一个丑陋的事情reintepret_cast没有办法避免它。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将字符串编码为数字,以便在scikit-learn中使用它

来自分类Dev

将R.layout。*解析为整数值以便在充气机中使用

来自分类Dev

将元素的ID分配给.hover()上的变量,以便在click事件中使用

来自分类Dev

mysql:将数组设置为变量,以便在“ IN”子句中使用

来自分类Dev

将 3 个单独的列合并为一列,以便在 IN 子句中使用

来自分类Dev

如何将VBA long&HFFFFFFF0转换为uint以便在C#中使用?

来自分类Dev

如何在C#中获得不可为空的T以便在函数中使用它?

来自分类Dev

如何将包装DLL连接到API DLL以便在C#项目中使用?

来自分类Dev

如何将文件复制到目标,以便在运行任务中使用它们?

来自分类Dev

将标签添加到mp3中以便在音乐播放器中使用

来自分类Dev

如何将 Activity 对象传递到 onBindViewHolder 方法中,以便在 getScaledBitmap 方法中使用该对象

来自分类Dev

Xcode 7.3如何将现有的iPhone应用程序转换为通用应用程序,以便在iOS中使用iPad

来自分类Dev

Xcode 7.3如何将现有的iPhone应用程序转换为通用应用程序,以便在iOS中使用iPad

来自分类Dev

在Julia中键入稳定函数,以便在使用浮点输入时进行一般分配

来自分类Dev

用于将任何lambda函数(包括捕获lambda)转换为std :: function对象的模板

来自分类Dev

用于将任何lambda函数(包括捕获lambda)转换为std :: function对象的模板

来自分类Dev

用于将任何lambda函数(包括捕获lambda)转换为std :: function对象的模板

来自分类Dev

XYZ格式的点云生成,以便在GLAP中使用

来自分类Dev

std :: function指针错误:无法将&A :: a转换为std :: function <> &&

来自分类Dev

如何将图像文件夹添加到CMake项目,以便在c ++可执行文件中使用这些图像?

来自分类Dev

[Ember.js]将模板助手创建的模板助手作为属性传递给组件,以便在组件模板中使用它?

来自分类Dev

在Julia中键入稳定函数以便在使用浮点输入时进行一般分配

来自分类Dev

将崇高文本片段保存在目录中,以便在其他PC上重复使用

来自分类Dev

使用FFmpeg将4K视频重新编码为H.265 / HEVC,以便在QuickTime中播放

来自分类Dev

将崇高文本片段保存在目录中,以便在其他PC上重复使用

来自分类Dev

在Delphi中使用Lambda函数

来自分类Dev

在python中使用lambda函数

来自分类Dev

在lambda函数中使用反向

来自分类Dev

在python中使用lambda函数

Related 相关文章

  1. 1

    将字符串编码为数字,以便在scikit-learn中使用它

  2. 2

    将R.layout。*解析为整数值以便在充气机中使用

  3. 3

    将元素的ID分配给.hover()上的变量,以便在click事件中使用

  4. 4

    mysql:将数组设置为变量,以便在“ IN”子句中使用

  5. 5

    将 3 个单独的列合并为一列,以便在 IN 子句中使用

  6. 6

    如何将VBA long&HFFFFFFF0转换为uint以便在C#中使用?

  7. 7

    如何在C#中获得不可为空的T以便在函数中使用它?

  8. 8

    如何将包装DLL连接到API DLL以便在C#项目中使用?

  9. 9

    如何将文件复制到目标,以便在运行任务中使用它们?

  10. 10

    将标签添加到mp3中以便在音乐播放器中使用

  11. 11

    如何将 Activity 对象传递到 onBindViewHolder 方法中,以便在 getScaledBitmap 方法中使用该对象

  12. 12

    Xcode 7.3如何将现有的iPhone应用程序转换为通用应用程序,以便在iOS中使用iPad

  13. 13

    Xcode 7.3如何将现有的iPhone应用程序转换为通用应用程序,以便在iOS中使用iPad

  14. 14

    在Julia中键入稳定函数,以便在使用浮点输入时进行一般分配

  15. 15

    用于将任何lambda函数(包括捕获lambda)转换为std :: function对象的模板

  16. 16

    用于将任何lambda函数(包括捕获lambda)转换为std :: function对象的模板

  17. 17

    用于将任何lambda函数(包括捕获lambda)转换为std :: function对象的模板

  18. 18

    XYZ格式的点云生成,以便在GLAP中使用

  19. 19

    std :: function指针错误:无法将&A :: a转换为std :: function <> &&

  20. 20

    如何将图像文件夹添加到CMake项目,以便在c ++可执行文件中使用这些图像?

  21. 21

    [Ember.js]将模板助手创建的模板助手作为属性传递给组件,以便在组件模板中使用它?

  22. 22

    在Julia中键入稳定函数以便在使用浮点输入时进行一般分配

  23. 23

    将崇高文本片段保存在目录中,以便在其他PC上重复使用

  24. 24

    使用FFmpeg将4K视频重新编码为H.265 / HEVC,以便在QuickTime中播放

  25. 25

    将崇高文本片段保存在目录中,以便在其他PC上重复使用

  26. 26

    在Delphi中使用Lambda函数

  27. 27

    在python中使用lambda函数

  28. 28

    在lambda函数中使用反向

  29. 29

    在python中使用lambda函数

热门标签

归档