C ++: помогите понять эту строку кода

0

Я искал способ получить доступ к vtable прямо через указатель и наткнулся на это сообщение: http://www.codeproject.com/Tips/90875/Displaying-vtable-when-debugging

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

void (**vt)() = *(void (***)())ptr;

ptr - указатель на объект. Как я могу расшифровать эту строку и как получить vt -адрес vt?

Спасибо.

Теги:
visual-studio
vtable
vptr

2 ответа

1
Лучший ответ

void (**vt)()
vt - указатель на указатель на некоторую функцию. Эта функция возвращает void и не принимает никаких параметров.
void (***)()
означает указатель на указатель на такую функцию (то есть один уровень указателя больше, чем выше).

Во-первых, вы отбрасываете ptr на такой трехуровневый указатель на функцию.
Затем вы получаете то, на что указывает (с единственным *), то есть двухуровневый указатель на функцию, т.е. тот же тип a переменная vt. Это означает, что вы можете назначить его для vt, и это будет исключительно то, что делает эта строка.

И почему?

В такой переменной x: void(*x)() может быть сохранен единственный указатель на функцию void-no-param-function. И не совсем связано, если вы хотите передать некоторый массив функции, вы передаете указатель. То есть. достаточно сохранить адрес массива в указателе для доступа к целому массиву (если длина известна).
Это означает, что void(**vt)() может хранить (адрес) массив указателей на функции.
Vtable - не что иное, просто массив указателей на функции.

Если у вас есть автомобиль класса с некоторыми переменными, такими как цвет и vtable, и он использует, например. 200 байт на объект. Указатель на автомобиль похож на указатель на 200-байтовый массив, и если вы получаете доступ к цвету в коде, компилятор просматривает этот цвет, например. байт 133 и генерирует доступ к нему.

Где vtable находится внутри этого объекта, определяется реализация, но часто в начале. Если у вас есть указатель на автомобиль, это указатель на массив из 200 байт, разделенный на некоторые указатели fucntion и некоторые другие данные после них...

=> Vtable, т.е. массив указателей функций, начинается с начального адреса автомобиля.
=> Если вы указали указатель на указатель на vtable, т.е. указатель на "массив указателей функций", т.е. указатель на "указатель на указатель на функцию" и уважение, что у вас есть массив vtable.

2

Фактическое местоположение _vtable в объекте зависит от компилятора. Код предполагает, что адрес _vtable сохраняется сначала в объекте (что, по-видимому, все современные компиляторы). Кроме того, существует только один vtable для каждого класса, который хранится в одном месте. Таким образом, каждый экземпляр имеет адрес для этого массива указателей на функции.

В принципе, вы создаете переменную с именем vt, то есть массив указателей на функции, которые возвращают void и не принимают никаких параметров. Затем вы инициализируете эту переменную содержимым, найденным в первом члене объекта (адрес vtable).

(void (***)())ptr

означает, что вы перенесите эту первую 4 (32-битную машину) или 8 (64-разрядную машину) на указатель на массив указателей функций, которые возвращают void и не принимают никаких параметров.

*(void (***)())ptr

возвращает содержимое этих 4 или 8 байтов, то есть адрес vtable.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню