У меня есть этот фрагмент кода, который регистрирует обратный вызов обработчика событий Boost asio. Ключевой точкой является значение pliny_store_ptr
в трех лог-точках psp. Каким-то образом захват работает не так, как я ожидаю.
// This gives me a db pointer that works.
sqlite3* pliny_store_ptr = sqlite_open_v2(...);
LOG_INFO << "psp[1]: " << pliny_store_ptr;
UdpServer udp_server(
io_service_main, udp_port,
[&pliny_store_ptr, &callback, &io_service_worker,
&work_thread_idle](const string& epistula_stream) -> string {
LOG_INFO << "psp[2]: " << pliny_store_ptr;
return "IRL a function returning a string";
});
io_service_main.run();
LOG_INFO << "psp[3]: " << pliny_store_ptr;
Известно, что класс UdpServer работает в других контекстах, включая собственные модульные тесты. Это просто оболочка для некоторых обработчиков чтения asio asyn c: она прослушивает udp_port
сообщения. Третий аргумент, лямбда, является обратным вызовом, который UdpServer будет вызывать в процедуре завершения обработчика чтения asio asyn c. Все довольно обычные вещи.
(Все это выполняется в одном потоке. И, очевидно, постоянное возвращаемое значение действительно является функцией обратного вызова, которая использует те переменные, которые захватывает лямбда-выражение.)
Вывод работает это ниже. Обратите внимание на три точки журнала psp: в 1 и 3 значение равно 0x24632b8
, но в 2 (зафиксированное значение) оно равно 0x293b570
. Поэтому неудивительно, что вызов sqlite3 выдает ошибку 21: дескриптор передаваемой базы данных недопустим.
Вопрос в том, почему я не фиксирую правильное значение для pliny_store_ptr
в лямбде. Я попытался сделать лямбду непостоянной, думая, что sqlite3 захочет изменить то, на что указывает, и, возможно, я бы неправильно понял кое-что о константности указателей в лямбдах. Кажется, не имеет значения. Первоначально я передал pliny_store_ptr
по значению, которое, как я думал, будет работать (это указатель, а не содержимое), но также не сработало примерно так же.
Кто-нибудь видит, что я неправильно понимаю?
2020-Mar-29 16:55:58.373760: psp[1]: 0x24632b8
2020-Mar-29 16:55:59.378286: psp[2]: 0x293b570
2020-Mar-29 16:56:00.377609: psp[2]: 0x293b570
2020-Mar-29 16:56:01.376113: psp[2]: 0x293b570
2020-Mar-29 16:56:02.376682: psp[2]: 0x293b570
2020-Mar-29 16:56:03.375930: psp[2]: 0x293b570
2020-Mar-29 16:56:04.376944: psp[2]: 0x293b570
2020-Mar-29 16:56:05.375787: psp[2]: 0x293b570
2020-Mar-29 16:56:05.831849: psp[2]: 0x293b570
2020-Mar-29 16:56:05.832640: INSERT INTO pliny_tasks (client_id, initiator_timestamp, registered_timestamp, campaign_id, reading_group_id, reading_group_type, user_id, device_id) VALUES (8864268719399569257, 1585500965829, 1585500965832, 0, 5, 'galley', 0, '');
2020-Mar-29 16:56:05.832789: Failed to insert task: err=21) - library routine called out of sequence
2020-Mar-29 16:56:06.376993: Quit requested, preparing to terminate pliny services.
2020-Mar-29 16:56:06.377428: Pliny services ready for termination.
2020-Mar-29 16:56:06.377676: psp[3]: 0x24632b8