I use ESP-32 and need to pass std::shared_ptr using FreeRTOS queue. However, it loose one link. I think that this is source of a problem:
#include <iostream>
#include <memory>
#define PRINT_USE_COUNT(p) std::cout << "Use count: " << p.use_count() << std::endl;
extern "C" {
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
}
class testClass {
public:
testClass() {
std::cout << "Class is constructed" << std::endl;
};
virtual ~testClass() {
std::cout << "Class is destructed" << std::endl;
};
};
struct container {
std::shared_ptr<testClass> field;
};
extern "C" void app_main(void) {
auto queue = xQueueCreate(1, sizeof(container));
auto p = std::make_shared<testClass>();
PRINT_USE_COUNT(p); // 1
{
container c;
c.field = p;
PRINT_USE_COUNT(p); // 2
xQueueSendToBack(queue, &c, 0);
PRINT_USE_COUNT(p); // 2
}
PRINT_USE_COUNT(p); // 1 (Ooops!)
{
container c;
assert(xQueueReceive(queue, &c, 0) == pdTRUE);
PRINT_USE_COUNT(c.field); // 1
}
// Class is destructed
std::cout << "Test finished" << std::endl;
vQueueDelete(queue);
}
So there is a pointer in queue, but it isn't counted!
How can I solve this issue (and keep using FreeRTOS queue if possible)? Using std::move doesn't help.
sound? It's hard to tell what you're doing without a minimal example of SoundControl implementation and without knowing how you declare and allocate soundqueueis aC(con)struct. I highly doubt it was designed with C++ classes in mind and as such it probably can't handle anything but PODs/trivial classes. I.e. no destructors and such. Looking at the documentation, it just accepts plainvoid *and copies it to its storage byte-by-byte. You won't be able to fix it unless they provide C++ API or at least a way to pass deleter.