Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Запустить нестатический метод... 
:(
    Опции темы
Абабо
Дата 17.5.2005, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 14.1.2005

Репутация: нет
Всего: 1



Вопрос к знатокам ANSI C++. Можно ли, не прибегая к ассемблеру, вызвать нестатический метод класса, имея лишь нетипизированный указатель (void*) на экземпляр этого класса и такой же указатель на нужный метод? Предполагается, что известен как список аргументов метода, так и тип его calling convention. Если это возможно, то как?
Заранее благодарю. smile

--------------------
С уважением, Абабо.
PM MAIL   Вверх
Fantasist
Дата 17.5.2005, 20:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата
Предполагается, что известен как список аргументов метода, так и тип его calling convention.


Эта информация известна на этапе написании кода или на этапе выполнения?


--------------------
Волны гасят ветер...
PM MAIL   Вверх
chipset
Дата 17.5.2005, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 27
Всего: 165



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


--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
Fantasist
Дата 17.5.2005, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата(chipset @ 17.5.2005, 17:19)
А если сделать указатель на функцию с аналогичной сигнатурой и подменить адрес на адрес твоей функции?


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


Добавлено @ 20:43
На всякий случай, если известно, что будем вызывать:

Код


class P
{
public:
  int f();  
}


typedef int (*FPointer)(void*);

{
  void *obj; //указатель на экзепляр класса
  FPointer fp; //адресс метода f.
  
  fp(obj); //вызов
}




Интересно только как адрес метода достается. Чтением виртуальной таблицы? Или как?




--------------------
Волны гасят ветер...
PM MAIL   Вверх
chipset
Дата 17.5.2005, 20:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 27
Всего: 165



Плин, тогда придется вручную формировать класс. Вроде бы этим, хотя я не уверен, занимается такая вещь как Reflection.
Добавлено @ 20:47
Цитата(Fantasist @ 17.5.2005, 10:33)
Интересно только как адрес метода достается. Чтением виртуальной таблицы? Или как?

Я думаю что ему по сети или ещё как-то приходит целый блок памяти скопированный с класса и указатели на мемберы.


--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
Fantasist
Дата 17.5.2005, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата(chipset @ 17.5.2005, 17:46)
Вроде бы этим, хотя я не уверен, занимается такая вещь как Reflection.


Reflection - это (не знаю откуда пошло, но похоже от Java) обзывание средств доступа к RTTI. Так как в С++ RTTI очень слабенькая, то особо там мутить нечего.


Цитата(chipset @ 17.5.2005, 17:46)
Я думаю что ему по сети или ещё как-то приходит целый блок памяти скопированный с класса и указатели на мемберы.


Что-то сильно сомневаюсь.




--------------------
Волны гасят ветер...
PM MAIL   Вверх
Дрон
Дата 17.5.2005, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 93



Если я правильно тебя понял:

Код

class CMyClass
{
      int Method(double);
}

void *ptr; // указывает на объект

void *method; // указывает на метод

Могу обрадовать, что решение, не выходящее за рамки обычного С++ существует smile
Код

int Call(void *clsPtr, void *mtdPtr, double param)
{
    union 
    {
        void *vptr;
        int (CMyClass::*mptr)(double);
    };
    vptr = mtdPtr;
    return (((CMyClass*)clsPtr)->*mptr)(param);
}

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


--------------------
Да. Именно так.
PM   Вверх
Fantasist
Дата 17.5.2005, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Код

    union 
    {
        void *vptr;
        int (CMyClass::*mptr)(double);
    };
    vptr = mtdPtr;
    return (((CMyClass*)clsPtr)->*mptr)(param);


Такое преобразование имеет смысл только, если перед этим было проделанно обратное преобразование (mptr к void*). Я ведь не даром поднял вопрос о том, как получается адрес метода.
Дело в том, что тип CМyClass::* - не содержит адрес метода, а лишь информацию достадочную для того, чтобы его вызвать.

Это сообщение отредактировал(а) Fantasist - 17.5.2005, 23:22


--------------------
Волны гасят ветер...
PM MAIL   Вверх
Дрон
Дата 17.5.2005, 23:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 93



Fantasist
Цитата(Fantasist @ 18.5.2005, 00:22)
только, если перед этим было проделанно обратное преобразование (mptr к void*)

Да. Я сам не совсем понимаю как он получил этот указатель... Но на вопрос-то ответил smile


--------------------
Да. Именно так.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0783 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.