gpt4 book ai didi

c++ - CPP 成员对 C 回调包装器的反馈

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:06:22 25 4
gpt4 key购买 nike

我一直在绞尽脑汁地使用带有 C++ 回调的 C 库。例如我有以下方法:

int button(int iconid, const char *label, UIhandler handler);

我可以用作:

button(ICON_COLOR, "Some text", callback);

我现在想使用一个 C++ 成员,但我不能按原样传递它的指针。因此,根据对 SO 的发现和阅读其他实现,我有以下包装代码:

template <typename T>
struct Callback;

template <typename Ret, typename... Params>
struct Callback<Ret(Params...)> {
template <typename... Args>
static Ret callback(Args... args) { return func(args...); }
static std::function<Ret(Params...)> func;
};

// Initialize the static member.
template <typename Ret, typename... Params>
std::function<Ret(Params...)> Callback<Ret(Params...)>::func;

template <class InstanceClass>
UIhandler ofxBluiCptr(InstanceClass * instance, void (InstanceClass::*instanceMethod)(int, UIevent))
{
Callback<void(int, UIevent)>::func = std::bind( instanceMethod, instance, std::placeholders::_1, std::placeholders::_2 );
void (*c_func)(int, UIevent) = static_cast<decltype(c_func)>(Callback<void(int, UIevent)>::callback);
return c_func;
}

我现在可以按如下方式使用 C 库:

button(ICON_COLOR, "Some text", ofxBluiCptr(this, &ofApp::buttonPressed ))

它有效,但我很难理解它是如何工作的。任何人都可以对此提供反馈,或者评论使用这种方式是否安全吗?

最佳答案

如果我没理解错的话,你想传递成员函数,为此你需要“绑定(bind)”到它 this

有两种简单的方法可以做到这一点。如果您可以获得 this 指针,只需创建一个静态包装函数,它将调用成员,使用 this this 指针。

如果您无法这样做,则创建一个 lambda 来捕获 this,并接受您要传递给 CB 的参数。使用此 lambda 作为您的 CB。

auto myCB = [this](auto & param1) { this->member(param1);}

顺便说一句,每当您看到 bind 时,请检查您是否无法使用 lambda 来创建更简单的代码。大多数情况下你会的。

这有一个缺点,就是不能在需要 C 风格函数指针的地方使用它。

要解决这个问题,您可以用相关实例包装每个 CB。例如:

struct Wrapper{
static CB_instance* instance;
static void myCallback(Param1 p1, Param2 p2) {
instance->callback(p1, p2);
}

现在,Wrapper::myCallback 可以用作 C 函数指针。如果您将其模板化,您将获得代码,与您开始使用的代码非常相似......

关于c++ - CPP 成员对 C 回调包装器的反馈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49650662/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com