通过实用程序 fn 将捕获的 lambda 传递给 C 样式回调 - 错误
Passing capture-ful lambda to C-style callback through utility fn - error
我想借助实用程序函数将捕获的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*>()`
我不明白为什么。
现场示例
更新:
我要强调的是,实用程序函数c_style_callback
对于将来遇到此问题的其他人非常有用。这是一个比这里答案中的解决方案更灵活的解决方案,因为这个解决方案支持自定义回调签名(不确定如何描述它(。
我的问题更多的是关于使用它,而不是关于"将捕获作为函数指针的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 void (*fpActionCallback_t)(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status, const char *pReceivedJsonDocument, void *pContextData, void *pClientData);
或更改返回类型get_callback
。
相关文章:
- 架构决策:返回std::future还是提供回调
- 正在为Xtensa simcall函数编写回调函数
- 如何在C++中使用非静态成员函数作为回调函数
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 用于在回调中调用解析器的设计模式
- 如何使用C++对象的成员函数作为 C 样式回调?
- Java从C++回调到C++回调
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 从不同的 cpp 调用回调函数会导致bad_function_call
- pcap_handler回调仅在使用 NPCAP v0.9991 时包含空数据包
- 不带轮询的 SDL2 事件回调
- C++存储带有可变参数的回调
- 如何使用 Node-addon-API 实现 node-nan 回调
- 访问类C++ C 样式回调
- 通过实用程序 fn 将捕获的 lambda 传递给 C 样式回调 - 错误
- C++ 11 - 将 C 样式回调绑定到类成员函数
- 使 C 样式回调对象面向
- 在返回值和"回调"之间做出决定时的样式与一致性
- 如何在对象上获取一个方法,以便将其作为C样式回调传递