Адрес функции в VStudio (2003)
От: _dg  
Дата: 27.10.04 12:22
Оценка:
Пожалуйста подскажите как решить такую задачу:

Имеется функция
void __stdcall TimerCallbackProto(DWORD hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
код
}

Как получить ее адрес в переменную ULONG src?

При простом присваивании src=TimerCallbackProto, src получает неверный адрес.
Еще вопрос можно ли это сделать без *_cast'ов и введения процедурного типа?


27.10.04 22:43: Перенесено модератором из 'C/C++' — Павел Кузнецов
Re: Адрес функции в VStudio (2003)
От: Antikrot  
Дата: 27.10.04 14:15
Оценка:
Здравствуйте, _dg, Вы писали:

_dg>При простом присваивании src=TimerCallbackProto, src получает неверный адрес.

Вряд ли можно вообще сделать то, что тебе надо. Скорее всего, после вот такого присваивания в src лежит адрес инструкции jmp [TimerCallbackProto] в таблице. Теоретически, можно взять 6 байт (код команды jmp) с этого адреса и вытащить оттуда реальный адрес. Но далеко не факт, что это именно так (там может быть указатель на какой-нить код, используемый дебугером и т.д.)
А вообще, зачем так делать? Ведь вызов-то по полученному в src "неправильному" адресу все равно доберется до TimerCallbackProto...
Или ты пишешь динамически тело этой функции? Если да, то я в принципе такую проблему обходил, могу сказать как...
Re[2]: Адрес функции в VStudio (2003)
От: _dg  
Дата: 27.10.04 14:58
Оценка:
Здравствуйте, Antikrot, Вы писали:
_dg>>При простом присваивании src=TimerCallbackProto, src получает неверный адрес.
A>Вряд ли можно вообще сделать то, что тебе надо. Скорее всего, после вот такого присваивания в src лежит адрес инструкции jmp [TimerCallbackProto] в таблице. Теоретически, можно взять 6 байт (код команды jmp) с этого адреса и вытащить оттуда реальный адрес. Но далеко не факт, что это именно так (там может быть указатель на какой-нить код, используемый дебугером и т.д.)


Мдаа... как там все запутано... Может лучше плюнуть на все и сделать через процедурный тип?


A>А вообще, зачем так делать? Ведь вызов-то по полученному в src "неправильному" адресу все равно доберется до TimerCallbackProto...

A>Или ты пишешь динамически тело этой функции? Если да, то я в принципе такую проблему обходил, могу сказать как.

Совершенно верно, мне в рантайме надо подправить в ней два адреса. Все уже работает, за исключением получения адреса самой процедуры, так что очень инетересно узнать как это можно обойти

Чтобы быть более конкретным уточню что я занимаюсь такой довольно банальной вещью, как создание таймера для конкретного экземпляра класса (т.е. подгоняю callback таймера под функцию-член класса)
Re[3]: Адрес функции в VStudio (2003)
От: Wild_Jerboa  
Дата: 27.10.04 23:47
Оценка:
С++ only and forever!!! Нет паскалям!


#include <windows.h>

class CTimer {
private:

    struct micro_prg{
        unsigned char pop_eax;    // 0x58 pop eax
        unsigned char push;        // 0x68 push this
        void *_this;
        unsigned char push_eax;    // 0x50 push eax
        unsigned char jmp;        // 0xE9 jmp fOnTimer
        void *method;
    } m_prg;

    char *fMsg;
    int fId;

    static void __stdcall fOnTimer(CTimer *_this,
            HWND hwnd,
            UINT uMsg,
            UINT_PTR idEvent,
            DWORD dwTime)
    {
        MessageBox((HWND)0xfa, _this->fMsg, "Timer message", MB_OK);
    }

public:
    CTimer(char *aMsg){
        m_prg.pop_eax = 0x58;
        m_prg.push = 0x68;
        m_prg._this = this;
        m_prg.push_eax = 0x50;
        m_prg.jmp = 0xE9;
        m_prg.method = (void *)((DWORD)fOnTimer-(DWORD)(&m_prg) - 12);
        fId = SetTimer(NULL, NULL, 2000, (TIMERPROC)&m_prg);
        fMsg = aMsg;
    }
};

int __stdcall WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
{
    CTimer timer1("timer 1");
    CTimer timer2("timer 2");
    MSG uMsg;
    GetMessage(&uMsg, NULL, 0, 0);
    DispatchMessage(&uMsg);
    return 0;
}


Всё компилится и работает
Re[3]: Адрес функции в VStudio (2003)
От: FR  
Дата: 30.10.04 11:15
Оценка:
Здравствуйте, _dg, Вы писали:

_dg>Чтобы быть более конкретным уточню что я занимаюсь такой довольно банальной вещью, как создание таймера для конкретного экземпляра класса (т.е. подгоняю callback таймера под функцию-член класса)


А зачем это делать, извиняюсь через одно место? Не проще ли хранить где ни будь (хоть в std::map) привязку id таймера к конкретному экземпляру?
... << RSDN@Home 1.1.3 stable >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.