Привести указатель на функцию-член к обычному указателю
11547 просмотра
6 ответа
В настоящее время у меня есть класс такого вида, сокращенный для простоты:
class MyClass {
public:
MyClass();
void* someFunc(void* param);
}
Теперь мне нужно вызвать функцию такого типа (не принадлежащую ни к какому классу и которую я, к сожалению, не могу изменить ), но которую я должен вызвать в любом случае:
void secondFunc(int a, int b, void *(*pCallback)(void*));
Теперь мне нужно передать адрес someFunc экземпляра.
Неработающий образец:
MyClass demoInstance;
// some other calls
secondFunc( 1, 2, demoInstance::someFunc() );
Я пробовал также с приведениями типа:
(void* (*)(void*)) demoInstance::someFunc;
reinterpret_cast<(void* (*)(void*))>(demoInstance::someFunc);
Как я могу вызвать эту функцию с функцией-членом класса в качестве параметра, чтобы она могла использовать ее в качестве обратного вызова?
Любая идея или замечание приветствуется. Спасибо и привет Тобиас
Автор: Atmocreations Источник Размещён: 13.11.2019 11:50Ответы (6)
5 плюса
Разница между функцией C и функцией-членом C ++ заключается в том, что функция C использует соглашение о вызовах cdecl , в то время как функции-члены используют это соглашение о вызовах (и вы даже не можете получить их адрес!).
Как я понимаю, вы действительно хотите, secondFunc()
чтобы это вызывало функцию-член определенного экземпляра класса (давайте назовем это this
). Ну, адреса функций-членов всех экземпляров определенного класса одинаковы. Чтобы передать указатель на объект, вам понадобится боковой канал. В этом случае это может быть статическая переменная. Или, если вы хотите поддержку MT, вам придется использовать Thread Local Storage (TLS),
Это требует одного обратного вызова для каждого SomeFunc
члена типа, но в любом случае вам понадобится диспетчер.
8 плюса
Вы не можете вызвать функцию-член напрямую. Указатели на функции-члены не относятся к указателям на функции.
Вам нужно как-то обернуть его в совместимую функцию. Однако, если ваша внешняя функция (та, которая принимает указатель функции в качестве аргумента) не является повторно входящей и не предоставляет дополнительный аргумент для использования указателем функции, вы не сможете передать экземпляр, на который член Функция работает, поэтому вы не сможете сделать звонок.
Автор: Jonathan Grynspan Размещён: 18.11.2010 01:061 плюс
Существует множество способов сделать это. Поскольку имена C ++ искажены, вы не можете напрямую использовать их для нестатических функций. Однако, поскольку нестатические функции имеют те же сигнатуры, что и функции C, вы можете напрямую использовать их в качестве обратных вызовов. Так что для нестатических функций у вас могут быть обертки статических функций. Эта страница подробно объясняет этот подход.
Автор: Sridhar Iyer Размещён: 18.11.2010 01:310 плюса
class MyClass
{
public:
MyClass();
void* someFunc(void* param);
};
void* callback(void*)
{
MyClass instance;
instance.someFunc(0 /* or whatever */);
}
void foo()
{
secondFunc( 1, 2, callback);
}
Автор: cababunga
Размещён: 18.11.2010 01:12
0 плюса
Смотрите этот образец:
#include <iostream>
class MyClass
{
public:
MyClass()
{
}
void* someFunc(void* param)
{
std::cout << "someFunc" << std::endl;
return (void*)0;
}
};
typedef void* (MyClass::*MemFun)(void*);
void secondFunc(int a, int b, MemFun fn)
{
MyClass* ptr = 0;
// This is dangerous! If the function someFunc do not operate the data in the class.
// You can do this.
(ptr->*fn)(0);
std::cout << "Call me successfully!" << std::endl;
}
int main()
{
secondFunc(1, 2, &MyClass::someFunc);
system("pause");
return 0;
}
Автор: lj_enjoylife
Размещён: 18.11.2010 02:12
0 плюса
Не видел части о невозможности изменить вторую функцию раньше.
Определите структуру с указателями на функцию-член и на объект:
struct MyData {
MyStruct *myInstance;
(void *)(MyStruct::myFunction)(void *data);
void * dataPointer ;
}
Создайте функцию, которая может вызывать правильный метод:
void *proxyFunc( MyData *data)
{
return (data->myInstance->*(data->myFunction))(data->dataPointer);
}
Затем вызовите функцию 2 как:
MyData dataP = { someInstance, &MyStruct::someFunc, &dataPtr };
secondFunc(proxyFunc, &dataP);
Автор: rldrenth
Размещён: 18.11.2010 01:13
Вопросы из категории :
- c++ What are the barriers to understanding pointers and what can be done to overcome them?
- c++ Какой самый простой способ для анализа файла INI в C ++?
- c++ Когда вы должны использовать «друг» в C ++?
- c++ Как вы очищаете переменную stringstream?
- c++ В C ++ конструктор и деструктор могут быть встроенными функциями?
- c++ Что такое виртуальный базовый класс в C ++?
- pointers Как вы передаете функцию в качестве параметра в C?
- pointers Regular cast vs. static_cast vs. dynamic_cast
- pointers Каковы различия между переменной-указателем и ссылочной переменной в C ++?
- pointers Почему я не могу конвертировать 'char **' в 'const char * const *' в C?
- pointers Что такое умный указатель и когда я должен его использовать?
- casting Приведите int к перечислению в C #
- casting Синтаксические стили C ++
- casting Приведение списка <int> в список <string> в .NET 2.0
- casting Зачем использовать static_cast <int> (x) вместо (int) x?
- casting Прямое приведение против оператора "как"?