Сейчас на форуме: hgdagon, asfa (+4 невидимых)

 eXeL@B —› Программирование —› Безобразие с типами С++
Посл.ответ Сообщение

Ранг: 4.7 (гость)
Активность: 0=0
Статус: Участник

Создано: 05 марта 2007 06:23
· Личное сообщение · #1

Привет всем. А вопрос собственно такой: как загнать в int (хоть void*) адрес публичной функции члена? Нп:
class A:
{
public:
void func(){}
};
void mian()
{
A* b;
int adr_func = ... b->func; (может A::func.. нинаю я)
}

заранее спасибо



Ранг: 39.1 (посетитель)
Активность: 0.030
Статус: Участник

Создано: 05 марта 2007 06:47 · Поправил: Gelios
· Личное сообщение · #2

#include <stdio.h>

class A
{
public:
static void func()
{
printf("Test
");
}
};

void main()
{
void* _ptr;
_ptr = &(A::func);
_asm
{
call _ptr
}
}


если функция не статическая, то тогда хз



Ранг: 4.7 (гость)
Активность: 0=0
Статус: Участник

Создано: 05 марта 2007 07:19 · Поправил: jasfasola
· Личное сообщение · #3

Большое спасибо. Вот только target не х86 а ARMI но с вызовом как нить разаерусь



Ранг: 191.8 (ветеран), 46thx
Активность: 0.170
Статус: Участник

Создано: 05 марта 2007 09:12
· Личное сообщение · #4

Книжка есть - иногда туда заглядываю
на бумаге у меня правда на русском
Глянь мож пригодится

O'Reilly - C++ in a Nutshell By Ray Lischner - May 2003
club.shelek.com/download.php?id=187



Ранг: 4.7 (гость)
Активность: 0=0
Статус: Участник

Создано: 05 марта 2007 10:02 · Поправил: jasfasola
· Личное сообщение · #5

О пацаны уже нашел :] вернее сначала нашел инфу об указателях на функции - члены, а потом сам справился.

#include "stdafx.h"

class A
{
public:
A(){}
~A(){}
void func(int param)
{
printf("Hello World!
");
}

};

int main(int argc, char* argv[])
{
A* p = new A;
void(A::*_ptr)(int param);
_ptr = p->func;
int* temp_ptr = (int*) &_ptr;
int addr_func = (int) *temp_ptr;
((void(__stdcall*)(int))addr_func)(1);
return 0;
}




Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 05 марта 2007 13:36 · Поправил: s0larian
· Личное сообщение · #6

Кста, на С++ с templates можно сделать подобное используя алгоритмы и templated functors. Например используя boost + STL:


class StatusHandler
{
public:
virtual void OnStep() = 0;
};

std::for_each(ovservers_.begin(), ovservers_.end(),
boost::bind(&StatusHandler::OnStep, _1));


P.S. это Observer design pattern



Ранг: 20.8 (новичок)
Активность: 0.010
Статус: Участник

Создано: 09 марта 2007 06:06
· Личное сообщение · #7

s0larian пишет:
используя boost


Есть вариант пошустрее, правда там хак, но всё равно довольно интересно:
--> Fast Delegate <-- http://www.codeproject.com/cpp/FastDelegate.asp




Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 09 марта 2007 09:18 · Поправил: s0larian
· Личное сообщение · #8

Player, хе хе, не парь мозги Вся чихня с functors которые создаются на лету на стеке становится inline. Только что посмотрел в VS2005 release build - там два десятка инсткукций, которые проверяют есть ли такой метод в vtable, берут начало контейнера и вызывают for_each(). Ну а тот, в случае вектора, просто вызывает функцию через полученный указатель для кажного элемента в своём массиве.

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



Ранг: 163.7 (ветеран)
Активность: 0.070
Статус: Участник

Создано: 10 марта 2007 01:10 · Поправил: S_T_A_S_
· Личное сообщение · #9

jasfasola пишет:
void(A::*_ptr)(int param);
_ptr = p->func;
int* temp_ptr = (int*) &_ptr;
int addr_func = (int) *temp_ptr;
((void(__stdcall*)(int))addr_func)(1);

Вызов не правильный. __stdcall не передаёт this в ecx.

Откастить поинтер на функцию член к другому типу можно и без копирования:
template<typename T>
static __forceinline
void * void_ptr_cast(T pf)
{
STATIC_ASSERT(sizeof(T) == sizeof(void*));
void ** const pp = reinterpret_cast<void**>(&pf);
return *pp;
}



 eXeL@B —› Программирование —› Безобразие с типами С++
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати