void AWS::subscribe(const char *topic,
pApplicationHandler_t iot_subscribe_callback_handler,
void* ptr) {
m_error =
::aws_iot_mqtt_subscribe(&m_client, topic, (uint16_t)std::strlen(topic),
QOS1, iot_subscribe_callback_handler, ptr);
}
затем маленькая утилита типа:
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)}; }
}
Теперь мы можем сделать:
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);
}
);
aws->subscribe(
topic,
task.get_callback<AWS_IoT_Client*, char*, uint16_t, IoT_Publish_Message_Params*>(),
task.get_pvoid()
);
Живой пример .
Как я уже понял, вы можете изменить класс AWS
, я бы сделал это:
template<class Handler>
void AWS::subscribe(const char *topic,
Handler iot_subscribe_callback_handler) {
auto task = utils::c_style_callback(iot_subscribe_callback_handler);
m_error =
::aws_iot_mqtt_subscribe(
&m_client,
topic,
(uint16_t)std::strlen(topic),
QOS1,
task.get_callback<AWS_IoT_Client*, char*, uint16_t, IoT_Publish_Message_Params*>(),
task.get_pvoid()
);
}
где subscribe
теперь принимает лямбду с подписью void(AWS_IoT_Client*, char*, uint16_t, IoT_Publish_Message_Params*)
.