使用类成员函数作为回调?

发布于 2024-12-11 21:25:42 字数 750 浏览 0 评论 0原文

我需要将一个成员函数传递给第三方外部方法:

box_self_intersection_d(mycallback);

box_self_intersection_d 是第三方外部静态方法,我无法修改它。 mycallback 是我想将其传递到 box_self_intersection_d 的方法,它是一个类函数,正在访问此类中的一些成员(对该类和 < code>mycallback)

我是否可以使用类成员函数作为回调而不将它们声明为静态函数?

编辑:mycallback的签名是(const box &boxA, const box &boxB),其中box是来自第三方提供商。

以及 签名 box_self_intersection_d

void box_self_intersection_d(RandomAccessIterator begin,RandomAccessIterator end,Callback callback)

I would need a member function to be passed into a third party external method:

box_self_intersection_d(mycallback);

The box_self_intersection_d is a third party external static method, and I cannot modify it. mycallback is a method I want to pass it into the box_self_intersection_d, it is a class function and is accessing some members in this class ( have full control for this class and the mycallback)

Is there anyway I can use class member functions as callbacks without declaring them as static functions?

Edit: the signature of mycallback is (const box &boxA, const box &boxB), where box is a special class from the third party provider.

And the signature for box_self_intersection_d is

void box_self_intersection_d(RandomAccessIterator begin,RandomAccessIterator end,Callback callback)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

假装不在乎 2024-12-18 21:25:43

我可以想到一个可怕的解决方案,这意味着将“this”和函数代码复制/推送到调用堆栈(或其他一些可以写入和可执行的调用者分配的段),并传递函数的地址到图书馆。然后,回调函数可以找到自己的代码地址,使用偏移量/指针算术提取“this”。并调用成员函数。应该适用于多线程。

我特此申请今年的“可怕黑客”奖,表彰该解决方案,该解决方案使开发人员感到身体不适,但如果项目经理用猎枪指着您的头,该解决方案仍然可能有效。

平均值,
马丁

There is a horrible solution that I can conceive of that means copying/pushing 'this' and function code to the calling stack, (or some other caller-allocated segment that can be made writeable and executable), and passing the address of the function to the library. The called-back function could then find its own code address, extract 'this' using an offset/pointer arith. and call a member function. Should work for multiple threads.

I hereby claim this years 'Gruesome Hack' award for a solution that makes developers feel physically ill but might still actually work if a project manager is pointing a shotgun at your head.

Rgds,
Martin

岛歌少女 2024-12-18 21:25:42

如果函数 box_self_intersection_d 采用函数作为参数,并且 mycallback 是类 MyClass 的方法,则可以使用 boost::绑定

box_self_intersection_d( boost::bind( &MyClass::mycallback, myClassInstance ) );

其中myClassInstance是类MyClass的实例。

If the function box_self_intersection_d takes a functional as parameters, and mycallback is a method of a class MyClass, you can use boost::bind:

box_self_intersection_d( boost::bind( &MyClass::mycallback, myClassInstance ) );

where myClassInstance is the instance of the class MyClass.

何时共饮酒 2024-12-18 21:25:42

如果回调接受用户定义数据的 void*,则可以使用静态包装函数将 void* 参数转换为类类型并调用成员函数。

示例:

static void Foo::callback_method(void* data) {
    static_cast<Foo*>(data)->mycallback();
}

void Foo::register_my_callback() {
    box_self_intersection_d(&Foo::callback_method, this);
}

大多数理智的回调库允许您将此 void* 参数传递给函数,作为在其中包含用户定义的数据的一种方式。如果没有,您将需要诉诸脏方法:

static Foo* Foo::callback_object;
static void Foo::callback_method() {
    callback_object->mycallback();
}

void Foo::register_my_callback() {
    callback_object = this;
    box_self_intersection_d(&Foo::callback_method);
}

一般来说,如果您需要传递一个函数,则没有其他方法:要么您有一个像 void* 这样的数据侧通道,您的库提供者似乎是这样省略(并且显然是库中的错误),或者您需要通过全局变量传输 this 指针。

If the callback accepts a void* for user-defined data, you can use a static wrapper function that casts the void* argument to the class type and calls your member function.

Example:

static void Foo::callback_method(void* data) {
    static_cast<Foo*>(data)->mycallback();
}

void Foo::register_my_callback() {
    box_self_intersection_d(&Foo::callback_method, this);
}

Most sane callback libraries allow you to pass this void* argument to the functions as a way to have user-defined data in it. If not, you'll need to resort to the dirty method:

static Foo* Foo::callback_object;
static void Foo::callback_method() {
    callback_object->mycallback();
}

void Foo::register_my_callback() {
    callback_object = this;
    box_self_intersection_d(&Foo::callback_method);
}

In general, if you need to pass a function, there is just no other way: Either you have a data side-channel like the void*, which your library provider seems to have omitted (and is clearly a bug in the library), or you need to transport the this pointer via a global variable.

弱骨蛰伏 2024-12-18 21:25:42

有几种可能的解决方法。您可以在这里查看:http://www.newty.de/fpt/callback。简而言之

,您可以:

  • 声明一个静态“包装方法”并将类的实例传递给它,
  • 或者将指向该对象的指针存储为全局变量。

希望有帮助,

There are a couple of possible workarounds. You can have a look here: http://www.newty.de/fpt/callback.html#member

In short, you can either:

  • declare a static "wrapper method" and pass the instance of the class to it,
  • or else store a pointer to the object as a global variable.

Hope that helps,

初与友歌 2024-12-18 21:25:42

一般来说,您没有提供签名 box_self_intersection_d()

,如果签名是

void box_self_intersection_d( void *cb );

或什至

void box_self_intersection_d( void (*cb)(const box&, const box&) );

那么您就无法将其传递给成员函数的指针。

原因是 sizeof(a_member_function)
sizeof(a_function_pointer)。如果是这种情况,我认为您被迫使用 thiton 的解决方案,并创建一个静态函数。

You haven't provided the signature box_self_intersection_d()

in general, if the signature is

void box_self_intersection_d( void *cb );

or even

void box_self_intersection_d( void (*cb)(const box&, const box&) );

then you cannot pass it a pointer to a member function.

The reason is that sizeof(a_member_function) is different than
sizeof(a_function_pointer). If this is the case, I think you are forced to use thiton's solution, and create a static function.

冷了相思 2024-12-18 21:25:42

由于是CGAL,所以回调实际上是一个模板参数。
它唯一的限制是“回调必须是 BinaryFunction 概念”。
也就是说,它可以是任何可以使用适当参数“调用”的东西。

这包括任何具有 void operator() (const box&, const box&) 成员函数的对象。
在您的类中实现该函数并为回调传递 *this 可能是最简单的解决方案。

Since it's CGAL, the callback is actually a template parameter.
Its only constraints are "Callback must be of the BinaryFunction concept".
That is, it can be anything that is "callable" with the proper parameters.

This includes any object with a void operator() (const box&, const box&) member function.
Implementing that function in your class and passing *this for the callback would probably be the simplest solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文