Как можно это сделать???
Нужно опеределить абсолютный адрес данной функции в CRT,
т.к. при вызове ее через extern определения позволяет лишь вызвать ее через смещение относительно текущего адреса машинной инструкции (таков компилятор). А мне нужен вызов через абсолютный адрес в адресном пространстве процесса.
05.01.04 00:06: Перенесено модератором из 'C/C++' — ПК
H e l l o, fallen!
[Sorry, skipped]
Может все-таки виртуальный адрес, а не абсолютный?
--
Всего хорошего, Слава. (
http://slava.users.otts.ru)
-= Если она считает, что вы много едите и спите, значит, это не ваша
мама. =-
Posted via RSDN NNTP Server 1.8 beta
reptile wrote:
> Нужно опеределить абсолютный адрес данной функции в CRT,
> т.к. при вызове ее через extern определения позволяет лишь вызвать ее через смещение относительно текущего адреса машинной инструкции (таков компилятор). А мне нужен вызов через абсолютный адрес в адресном пространстве процесса.
Почему возникает такой вопрос, зачем нужен абсолютный адрес?
С++ позволяет создать и проинициализировать указатель на функцию, и вызвать функцию с помощью этого указателя. Как представлен этот указатель обычно мало интересует.
--
Maxim Egorushkin
MetaCommunications Engineering
http://www.meta-comm.com/engineering/Posted via RSDN NNTP Server 1.8 beta
Здравствуйте, MaximE, Вы писали:
ME>Почему возникает такой вопрос, зачем нужен абсолютный адрес?
ME>С++ позволяет создать и проинициализировать указатель на функцию, и вызвать функцию с помощью этого указателя. Как представлен этот указатель обычно мало интересует.
Подозреваю, что вопрос возник именно на почве унификации указателя-на-функцию и возвращаемого значения GetProcAddress.
К счастью, на платформе wintel можно делать reinterpret-cast между void* и any_return(*)(any_params).
(На других платформах, особенно под досом — фиг!)
А может быть, товарищ делает фабрику функций, т.е. по символьному имени получает указатель.
Кроссплафторменное решение:
typedef void (*fn_type)(void); // для примера
typedef const char* id_type; // или GUID
// базовый API фабрики
extern fn_type fn_by_id(id_type id);
extern void register_fn(fn_type fn, id_type id, bool on);
// утилита для регистрации
class register_fn_helper
{
private:
fn_type fn_;
id_type id_;
public:
register_fn_helper(fn_type fn, id_type id) : fn_(fn), id_(id) { register_fn(fn_,id_,true); }
~register_fn_helper() { register_fn(fn_,id_,false); }
};
// пример:
void hello() { }
register_fn_helper reg_hello (hello, "hello");
/////////////////////////////////////////////
// реализация API
#include <map>
#include <cassert>
namespace {
typedef std::map<id_type,fn_type> map_id_fn_type;
map_id_fn_type map_id_fn;
void dummy(void) {}
};
void register_fn(fn_type fn, id_type id, bool on)
{
if(on)
{
std::pair<map_id_fn_type::iterator,bool> pib = map_id_fn.insert(std::make_pair(id,fn));
assert(pib.second); // вставлено, а не найдено
if(!pib.second)
pib.first->second = fn; // все равно перезапишем!
}
else
{
map_id_fn_type::iterator it = map_id_fn.find(id);
bool found = it != map_id_fn.end();
assert(found && it->second == fn); // найдено и инициализировано нами
if(found)
map_id_fn.erase(it); // сотрем, если найдено
}
}
fn_type fn_by_id(id_type id)
{
map_id_fn_type::const_iterator it = map_id_fn.find(id);
bool found = it != map_id_fn.end();
assert(found);
if(found)
return it->second;
else
return dummy;
}