Вызов функции-члена с пустым указателем на функцию - PullRequest
0 голосов
/ 30 июня 2010

Какой лучший способ вызвать функцию-член, если у вас есть объект и пустой указатель на функцию, указывающую на член?По сути, я хочу вызвать указатель на функцию с thiscall соглашением о вызовах.

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

Пример:

typedef void * (*GenericFptr)();
GenericFptr lookup(const char *);

class CFoo;

GenericFptr factoryfn(lookup("CFoo factory function"));
CFoo *foo = reinterpret_cast<CFoo *>(factoryfn());

GenericFptr memberfn(lookup("CFoo member function"));

// now invoke memberfn on foo

В настоящее время я использую union для преобразования указателя функции в указатель нафункция-член.Это ужасно и создает зависимости для деталей реализации компилятора:

class CFoo {
  public: 
  void *dummy() { return 0; }
};
typedef void * (CFoo::*FooMemberPtr)();

union {
  struct {
    // compiler-specific layout for pointer-to-member
    void *x, *y;
    GenericFptr ptr;
  } fnptr;
  FooMemberPtr memberfn;
} f;

f.memberfn = &CFoo::dummy; // init pointer-to-member
f.fnptr.ptr = memberfn;    // rewrite pointer

void *result = (foo->*f.memberfn)();

Ответы [ 4 ]

2 голосов
/ 30 июня 2010

Указатель на функцию-член не может быть сохранен в указателе на функцию, потому что он нуждается в большем количестве информации (например, в случае множественного наследования может потребоваться смещение до этого перед вызовом).Поэтому вы не можете обойтись без знания деталей реализации.

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

1 голос
/ 30 июня 2010

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

Я не думаю, что есть какой-то переносимый способ сделать то, что вы пытаетесь, хотя, если профсоюз, похоже, сработает, вам, вероятно, это сойдет с рук.Опять же, вам необходимо знать представление и соглашение о вызовах для этих методов для каждого компилятора, который вы хотите использовать для сборки bode.

Если вы знаете имя функции-члена, почему вы не можете просто сделать foo->dummy() например?В противном случае либо функция поиска должна предоставить полный указатель на функцию-член, либо библиотека должна была бы предоставить интерфейс оболочки C с обычными функциями, которым может быть передан этот указатель.

0 голосов
/ 21 марта 2014

В соответствии с ответом ниже это возможно в GCC, но не переносимо:

https://stackoverflow.com/a/5067992/705086

0 голосов
/ 30 июня 2010

Следующие две ссылки обеспечивают понимание и, возможно, решение. Обратите внимание, что вызов указателя на функцию-член с аргументом this обычно не работает, поскольку необходимо учитывать виртуальные методы, множественное и виртуальное наследование.

http://www.codeproject.com/KB/cpp/FastDelegate.aspx

http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...