how to pass a non static-member function as a callback?
1 2 3 4 5 6 7 8 9 | io_iterator_t enumerator; kern_return_t result; result = IOServiceAddMatchingNotification( mNotifyPort, kIOMatchedNotification, IOServiceMatching("IOFireWireLocalNode" ), serviceMatchingCallback, (void *)0x1234, & enumerator ); |
<规范>
1 | serviceMatchingCallback((void *)0x1234, enumerator); |
<规范>
如果我servicematchincallback然后它声明为静态的,但我不希望它是静态的。有没有办法通过它一个非静态回调函数?
谢谢你
ioServiceMatchingCallback的原型与非静态类方法不兼容(并且在技术上也与静态类方法不兼容),因此您将无法使用该方法。
但幸运的是,ioServiceAddMatchingNotification支持上下文指针(或者他们称之为refcon),它允许您创建不依赖全局数据的thunk。
您需要定义一个具有兼容链接(即extern"c")的回调。此函数将把refcon强制转换为对象指针,然后将调用转发给实例方法:
1 2 3 4 5 6 | extern"C" void io_callback(void *refcon, io_iterator_t iterator) { myclass *c = static_cast<myclass *>(refcon); c->real_callback(iterator); } |
然后,当您调用ioServiceAddMatchingNotification时,请确保向对象传递一个指针以进行refcon(这里假设您从成员函数调用ioServiceAddMatchingNotification,并且您有一个此指针):
1 2 3 4 5 6 7 | result = IOServiceAddMatchingNotification( mNotifyPort, kIOMatchedNotification, IOServiceMatching("IOFireWireLocalNode" ), serviceMatchingCallback, this, &enumerator ); |
您可以保持它是静态的,但是除了您想要的任何其他用户数据之外,还可以使用userdata来存储
不是直接的。
非静态函数指针(称为成员函数指针)具有隐藏的"this"参数,因此类型不匹配。静态函数没有"this"指针。
为了解决这个问题,您需要能够传入一个用户数据项,它是您要用作回调的对象的"this"指针。然后,指定传递用户数据的静态成员,将其转换为指向类对象的指针,并对其调用非静态成员。
查看您发布的代码,很难判断是否有用户数据对象,可能是最后一个,但=一个参数。
编辑我刚刚注意到您使用的是用户空间iokit api,而不是kext端,这使得本文不相关。
假设您在OSX内核中工作,那么实际上您可以这样做。可以使用
1 2 3 4 5 6 7 8 9 10 | IOServiceMatchingCallback mycb = OSMemberFunctionCast(IOServiceMatchingCallback, &myclassinstance, &MyClass::cb_method); result = IOServiceAddMatchingNotification( mNotifyPort, kIOMatchedNotification, IOServiceMatching("IOFireWireLocalNode" ), mycb, &myclassinstance, &enumerator); |
如果将此行放入构造函数(或任何实例方法)中,则应该能够执行此操作。InstanceMethod()以引用实例方法。
非
对不起,要避开跳岛可不容易。
不是。非静态方法需要一个对象来操作。如果只传递方法,还需要某种方法来告诉函数调用方法的对象。
不,一个非静态成员需要一个对象,而调用者(调用者)没有也不会提供对象。