Посл.ответ |
Сообщение |
Ранг: 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.03↘0 Статус: Участник
|
Создано: 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.17↘0 Статус: Участник
|
Создано: 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.17↘0 Статус: Участник системщик
|
Создано: 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.01↘0 Статус: Участник
|
Создано: 09 марта 2007 06:06 · Личное сообщение · #7
s0larian пишет:
используя boost
Есть вариант пошустрее, правда там хак, но всё равно довольно интересно:
--> Fast Delegate <-- http://www.codeproject.com/cpp/FastDelegate.asp
| Сообщение посчитали полезным: |
 Ранг: 387.4 (мудрец) Активность: 0.17↘0 Статус: Участник системщик
|
Создано: 09 марта 2007 09:18 · Поправил: s0larian · Личное сообщение · #8
Player, хе хе, не парь мозги  Вся чихня с functors которые создаются на лету на стеке становится inline. Только что посмотрел в VS2005 release build - там два десятка инсткукций, которые проверяют есть ли такой метод в vtable, берут начало контейнера и вызывают for_each(). Ну а тот, в случае вектора, просто вызывает функцию через полученный указатель для кажного элемента в своём массиве.
Ничего лишнего. Мораль проста - компилеры становятся всё умнее, не надо писать херню с указателями в таких случаях. (оговорюсь, что это, ессно, не подходит для случая когда в драйвере надо всё забить в пару инструкций)
| Сообщение посчитали полезным: |
Ранг: 163.7 (ветеран) Активность: 0.07↘0 Статус: Участник
|
Создано: 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;
}
| Сообщение посчитали полезным: |