Как преобразовать адрес метода класса в (void *) - PullRequest
0 голосов
/ 31 октября 2011
class Foo{
public:
    void Bar();
}

Это не обязательно должно быть безопасно, и меня не волнует указатель this. Мне просто нужно получить адрес функции Bar, находящейся в памяти на x86

void *address = (void *)&(Foo::Bar) не работает.

void *address = (void *)(&Foo::Bar) не работает.

void *address = (void *)Foo::Bar не работает.

РЕДАКТИРОВАТЬ: Позвольте мне уточнить это. Даже теоретически нельзя приводить указатель функции к объекту, потому что функции вполне могут быть расположены в другом пространстве памяти, в действительности они одинаковы. Как я упоминал ранее, это не должно быть ни безопасным, ни законным. Я добавил x86 тег к вопросу. Он должен работать только на gcc и MSVC на архитектуре x86.

Ответы [ 5 ]

9 голосов
/ 31 октября 2011

Вы не можете и не можете. Указатели на функцию-член не являются указателями (для объектов, т. Е. Они не T* для любого типа T). Они не обязательно и даже практически не вписываются в void*.

Единственное, что вы знаете о void*, - это то, что он достаточно большой, чтобы удерживать любой указатель объекта. Вот и все. Это даже не связано с обычными указателями свободных функций. При обработке вы можете определить аналог свободной функции для указателя void как typedef void(*voidf)();, но это только для свободных функций. Для функции указателей на член не существует вообще такой вещи, поскольку точная реализация PTMF зависит от природы класса (простой, полиморфный, виртуально производный, ...).

2 голосов
/ 31 октября 2011

Использовать сборку x86:

На MSVC:

__asm{
    mov eax, (Foo::Bar);
    mov address, eax;
}

На g ++:

__asm__ __volatile__("mov %1, %0":"=r"(address):"r"(&Foo::Bar));
0 голосов
/ 11 апреля 2016

Да, вы МОЖЕТЕ использовать чистый C ++, но во многих случаях просто для удовольствия или для проверки того, насколько хорошо вы работаете с указателями) Однако его можно использовать для добавления в программу более динамичного поведения.

struct A {
    void f1() {
        printf("f1:\n");
    }

    void f2() {
        printf("f2:\n");
    }
};

A a;

char f[sizeof(&A::f1)];
{
    void (A::*i)(void) = &A::f1;
    memcpy(f, &i, sizeof(f));
    (a.*i)();
}
(a.*(*(void (A::**)(void)) &f))();

{
    void (A::*i)(void) = &A::f2;
    memcpy(f, &i, sizeof(f));
    (a.*i)();
}
(a.*(*(void (A::**)(void)) &f))();
0 голосов
/ 31 октября 2011

Вы не можете преобразовать адрес функции объекта («метод») как глобальный «простой указатель».

Для вызова метода требуется ссылка на объект.

если у вас есть это:

class MyClass
{
  void Hello(char* AName) { ... }
}

void main()
{
  MyClass MyObject = new MyClass();
  MyObject->Hello("World");
  delete MyObject;
}

Программа внутренне выполняет что-то вроде этого:

void main()
{
  MyClass MyObject = new MyClass();
  Hello(MyObject, "World");
  delete MyObject;
}

Почему вы хотите это сделать?

Требуется адрес метода, поскольку решение проблемы .

Какая у вас проблема с программированием? Может быть, есть другой способ решить эту проблему.

0 голосов
/ 31 октября 2011

Нельзя привести указатель функции к пустому указателю.Проверьте C ++ faq для более подробной информации

...