#include "LibClass"
int my_callback(int args...) {
// к примеру как здесь адекватно присвоить переменной val значение
}
MyClass {
int val;
LibClass libclass;
public:
MyClass() {
libclass.register_callback(my_callback);
libclass.run();
}
// ... etc
};
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
int my_callback(int& val, std::recursive_mutex& m)
{
std::lock_guard<std::recursive_mutex> lock(m);
for(int i = 0; i < 10; ++i)
{
val++;
std::cout << val << '\t'
<< std::this_thread::get_id() << '\n';
}
return val;
}
int my_callback2(int& val, std::recursive_mutex& m)
{
std::lock_guard<std::recursive_mutex> lock(m);
for(int i = 0; i < 10; ++i)
{
val--;
std::cout << val << '\t'
<< std::this_thread::get_id() << '\n';
}
return val;
}
class LibClass
{
using callback = int(*)(int&, std::recursive_mutex&);
callback cbFn[2];
int idx;
public:
LibClass() : cbFn{nullptr, nullptr}, idx{}{}
void register_callback(callback cb)
{
cbFn[idx] = cb;
++idx;
}
void run(int& val, std::recursive_mutex& m)
{
std::thread t(std::ref(cbFn[0]), std::ref(val), std::ref(m));
std::thread t2(std::ref(cbFn[1]), std::ref(val), std::ref(m));
t.detach();
t2.detach();
}
};
class MyClass
{
int val;
LibClass libclass;
std::recursive_mutex m;
public:
MyClass() : val{}, libclass{}
{
libclass.register_callback(&my_callback);
libclass.register_callback(&my_callback2);
libclass.run(val, m);
}
void printVal()
{
m.lock();
std::cout << this << " val == " << val << '\n';
m.unlock();
}
};
int main()
{
MyClass m;
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Ждем
m.printVal();
}
один поток, потом второй
LibClass взялся и какая полная сигнатура у функции register_callback?my_callback(int args...) так невнятно написан? Какая точно должна быть сигнатура?register_callback семантическая пара на отмену регистрации callback-а?
int slv_callback(const PPSObjAttr attr, const IPPSObjectNotify::obj_status_t stat)register_callback еще не показал. Она должна что-то возвращать, чтобы потом использовать это для отмены регистрации. Каковы тип и поведение этого возвращаемого значения?
register_callback (как в хедере), может, там забрезжит какая-то надежда. this в качестве параметра (большинство библиотек поддерживают передачу void* параметра колбэкам). Переменную val нужно или объявить публичной, или сделать геттеры/сеттеры или объявить my_callback как friend для MyClass. Переменную нужно защитить так же, как для обычной многопоточной программы. На вскидку здесь могут подойти std::atomic или std::mutex.
MyClass {
std::atomic<int> val;
LibClass libclass;
int my_callback(params...);
public:
MyClass() {
libclass.register_callback( [this] (params...) { my_callback(params...); });
libclass.run();
}
// ... etc
};LibClass::register_callback() будет опциональный второй параметр типа void*. Работать это будет примерно так:int my_callback(int args..., void* priv) {
MyClass *instance = static_cast<MyClass*>(priv);
instance->val = ...;
}
MyClass {
std::atomic<int> val;
LibClass libclass;
public:
MyClass() {
libclass.register_callback(my_callback, this);
libclass.run();
}
// ... etc
};