как передать не статическую функцию членства как обратный вызов?

 
io_iterator_t enumerator;
kern_return_t   result;
result = IOServiceAddMatchingNotification(
             mNotifyPort,
             kIOMatchedNotification,
             IOServiceMatching( "IOFireWireLocalNode" ),
             serviceMatchingCallback, 
             (void *)0x1234,
             & enumerator );

serviceMatchingCallback((void *)0x1234, enumerator);

если я объявляю serviceMatchinCallback как статичный затем, он работает, но я не хочу, чтобы он был статичен. Существует ли способ передать его нестатическая функция обратного вызова?

Спасибо

7
задан BalusC 2 January 2013 в 17:06
поделиться

8 ответов

Вы можете сохранить его статическим, но используйте USERDATA для хранения указателя этого , в дополнение к тому, что другие другие пользовательские задачи (например, упаковывая их в структуру), а затем вызовите конкретный объект Обратный вызов от статической версии, вызывая This-> SomeCallback (где Это - это указатель, хранящийся в userdata, конечно).

4
ответ дан 6 December 2019 в 19:36
поделиться

Нет. Нестатические методы нуждаются в объекте для работы. Если бы вы имели просто пройти метод, вам также понадобится какой-то способ, чтобы сказать функцию, на который называть метод.

-121--3909854-

Нет, нестатический элемент ожидал объекта, а вызывающий абонент (Backer) не имеет и не предоставит одному.

0
ответ дан 6 December 2019 в 19:36
поделиться

Редактировать Я только что заметил, что вы используете пользовательский космический API Iokit, а не сторона Kext, что делает этот пост неактуальным.


Предполагая, что вы работаете в ядре OS X, вы действительно можете сделать это. Вы можете использовать макрос OSmumberFuncast MACRO для преобразования указателя функции элементов на простые указатель функции C, отметим, что его следует вызывать с первым аргументом, указывающим на экземпляр класса, например.

IOServiceMatchingCallback mycb = OSMemberFunctionCast(IOServiceMatchingCallback,
    &myclassinstance, &MyClass::cb_method);

result = IOServiceAddMatchingNotification(
             mNotifyPort,
             kIOMatchedNotification,
             IOServiceMatching( "IOFireWireLocalNode" ),
             mycb,
             &myclassinstance,
             &enumerator);
0
ответ дан 6 December 2019 в 19:36
поделиться

Прототип для IOSERVICEMATHINGCALLBACK не совместим с нестатическим классовым методом (и технически представляется , не совместимым со способом статического класса ), так что вы не сможете использовать это.

Но к счастью IOSERVICEADDDMatchingnotification поддерживает указатель контекста (или, как они называют его, refcon), который позволит вам создать Thunk, который не полагается на глобальные данные.

Вам необходимо определить обратный вызов с совместимым соединением (то есть extern «C»). Эта функция будет бросать ваш REFCON на ваш указатель объекта, а затем переслать звонок в свой метод экземпляра:

extern "C"
void io_callback(void *refcon, io_iterator_t iterator)
{
    myclass *c = static_cast<myclass *>(refcon);
    c->real_callback(iterator);
}

затем, когда вы вызываете IOSERVICEADDDMatchingNotification, обязательно передайте указатель на свой объект для REFCON (здесь я предполагаю, что вы звоните в IOSERVICEADDDMatchingNotification Из функции участника и у вас есть этот указатель):

result = IOServiceAddMatchingNotification(
             mNotifyPort,
             kIOMatchedNotification,
             IOServiceMatching( "IOFireWireLocalNode" ),
             serviceMatchingCallback, 
             this,
             &enumerator );
7
ответ дан 6 December 2019 в 19:36
поделиться

не напрямую.

Нестатический указатель функции (известный как указатель функции участника) имеет скрытый «этот» параметр, поэтому типы не совпадают. Статическая функция не имеет «этого» указателя.

Чтобы обойти это, вам нужно иметь возможность пройти в элементе пользовательских данных, который является «этот» указатель объекта, который вы хотите использовать в качестве обратного вызова. Затем укажите статический элемент, который передан пользовательские данные, преобразует его на указатель на объект класса и вызывает нестатический элемент на нем.

Глядя в код, который вы разместили, трудно сказать, есть ли объект пользовательских данных, возможно, последний-но = один параметр.

2
ответ дан 6 December 2019 в 19:36
поделиться

Нет. Нестатические методы нуждаются в объекте для работы. Если бы вы имели просто пройти метод, вам также понадобится какой-то способ, чтобы сказать функцию, на который называть метод.

0
ответ дан 6 December 2019 в 19:36
поделиться

Нерешитель функция имеет неявное этот параметр , и, таким образом, неверная подпись для обратного вызова.

Извините, не простой способ избежать острова прыжка.

0
ответ дан 6 December 2019 в 19:36
поделиться

Нет. Нестатические методы нуждаются в объекте для работы. Если бы вы имели просто пройти метод, вам также понадобится какой-то способ, чтобы сказать функцию, на который называть метод.

-121--3909854-

Неразвичная функция Статическая имеет неявное этот параметр , и, таким образом, неверно бы неверная подпись для обратного вызова.

Извините, не простой способ избежать острова прыжка.

-121--3909855-

Если вы поместите эту строку в своем конструкторе (или в любой методе экземпляра), то вы должны иметь возможность сделать это. INSTANCEMETHOD () ссылаться на метод экземпляра.

0
ответ дан 6 December 2019 в 19:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: