gpt4 book ai didi

c++ - 通过实用程序 fn 将捕获式 lambda 传递给 C 样式回调 - 错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:06:52 29 4
gpt4 key购买 nike

我想在实用函数的帮助下将捕获式 lambda 函数传递给 C 风格的回调:

#include <utility>
#include <iostream>
#include <array>

struct AWS_IoT_Client {};
struct IoT_Publish_Message_Params {
int payload[1024];
};

typedef enum {
SHADOW_ACK_TIMEOUT, SHADOW_ACK_REJECTED, SHADOW_ACK_ACCEPTED
} Shadow_Ack_Status_t;

typedef enum {
SHADOW_GET, SHADOW_UPDATE, SHADOW_DELETE
} ShadowActions_t;

typedef void (*pApplicationHandler_t)(AWS_IoT_Client *pClient, char *pTopicName, uint16_t topicNameLen,
IoT_Publish_Message_Params *pParams, void *pClientData);

typedef void (*fpActionCallback_t)(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status,
const char *pReceivedJsonDocument, void *pContextData);

struct AWS {
inline void subscribe(char*, pApplicationHandler_t, void*)
{
}

inline void get_shadow(fpActionCallback_t, void *)
{
}
};

AWS* aws = new AWS;

namespace utils {
template<class F>
struct c_style_callback_t {
F f;
template<class...Args>
static void(*get_callback())(Args..., void*) {
return [](Args...args, void* fptr)->void {
(*static_cast<F*>(fptr))(std::forward<Args>(args)...);
};
}
void* get_pvoid() {
return std::addressof(f);
}
};
template<class F>
c_style_callback_t< std::decay_t<F> >
c_style_callback( F&& f ) { return {std::forward<F>(f)}; }
}

int main() {
char someVar[1024]={0};

auto task2 = utils::c_style_callback(
[&] (const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status,
const char *pReceivedJsonDocument, void *pContextData) {
//sprintf(someVar, "%s", text);
}
);

aws->get_shadow(
task2.get_callback<const char*, ShadowActions_t, Shadow_Ack_Status_t, const char*, void*>(),
task2.get_pvoid()
);

auto task = utils::c_style_callback(
[&] (AWS_IoT_Client *pClient, char *topicName, uint16_t topicNameLen, IoT_Publish_Message_Params *params) {
char *text = (char *)params->payload;
sprintf(someVar, "%s", text);
}
);

但是,我没有收到不同回调的错误:

    char topic[] = "some topic";
aws->subscribe(
topic,
task.get_callback<AWS_IoT_Client*, char*, uint16_t, IoT_Publish_Message_Params*>(),
task.get_pvoid()
);
}

错误信息:

error: cannot initialize a parameter of type 'fpActionCallback_t' (aka 'void (*)(const char *, ShadowActions_t, Shadow_Ack_Status_t, const char *, void *)') with an rvalue of type 'void (*)(const char *, ShadowActions_t, Shadow_Ack_Status_t, const char *, void *, void *)': different number of parameters (5 vs 6)
task2.get_callback<const char*, ShadowActions_t, Shadow_Ack_Status_t, const char*, void*>()`

我不明白为什么。

live example

更新:

我要强调的是,实用函数 c_style_callback 对以后遇到此问题的其他人非常有用。这是比答案 here 中的解决方案更灵活的解决方案因为这个支持自定义回调签名(不知道如何描述)。

我的问题更多是关于使用它而不是关于“将捕获作为函数指针的 lambda”的问题。

最佳答案

查看您的回调定义:

typedef void (*pApplicationHandler_t)(AWS_IoT_Client *pClient, char *pTopicName, uint16_t topicNameLen, IoT_Publish_Message_Params *pParams, void *pClientData);

typedef void (*fpActionCallback_t)(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status, const char *pReceivedJsonDocument, void *pContextData);

以及每种情况下的回调参数:

task.get_callback<AWS_IoT_Client*, char*, uint16_t, IoT_Publish_Message_Params*>()

task2.get_callback<const char*, ShadowActions_t, Shadow_Ack_Status_t, const char*, void*>()

在第一种情况下,您有一个附加参数 void* pClientData,在后一种情况下您没有,即使 get_callback 将返回一个带有该附加参数的 lambda ,因为您返回的是 return [](Args...args, void* fptr),而不是 return [](Args...args)

因此,要么将您的第二个 typedef 更改为:

typedef void (*fpActionCallback_t)(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status, const char *pReceivedJsonDocument, void *pContextData, void *pClientData);

或者改变get_callback的返回类型。

关于c++ - 通过实用程序 fn 将捕获式 lambda 传递给 C 样式回调 - 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52272456/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com