Как из ассемблерной вставки в С++ коде вызвать метод класса
От: Misha87  
Дата: 26.12.08 07:25
Оценка:
У меня есть указатель на функцию — метод класса, у меня есть указатель на объект. Как из ассемблерной сатвки вызвать этот метод?
Re: Как из ассемблерной вставки в С++ коде вызвать метод кла
От: Зануда Россия http://pablo.newmail.ru
Дата: 26.12.08 08:07
Оценка:
Здравствуйте, Misha87, Вы писали:

M>У меня есть указатель на функцию — метод класса, у меня есть указатель на объект. Как из ассемблерной сатвки вызвать этот метод?


Если это x86 и Виндовс, то скорее всего, вы вызываете метод обычной инструкцией call, а указатель на экземпляр объекта и затем список всех переменных передаёте через стек в обратном порядке, т.е. последний параметр кладётся в стек первым, это всё только для типа __stdcall. Если используется __fastcall, то указатель на экземпляр и первые 2 параметра передаются через eax, edx, ecx, соответственно. А, вообще, более универсальный способ вы можете подглядеть у компилятора, собрав исполняшку и оттрассировав её.
Некто сказал: Щисливага программинья ;-)
Re[2]: Как из ассемблерной вставки в С++ коде вызвать метод
От: bazis1 Канада  
Дата: 26.12.08 08:47
Оценка:
Здравствуйте, Зануда, Вы писали:

З>Здравствуйте, Misha87, Вы писали:


M>>У меня есть указатель на функцию — метод класса, у меня есть указатель на объект. Как из ассемблерной сатвки вызвать этот метод?


З>Если это x86 и Виндовс, то скорее всего, вы вызываете метод обычной инструкцией call, а указатель на экземпляр объекта и затем список всех переменных передаёте через стек в обратном порядке, т.е. последний параметр кладётся в стек первым, это всё только для типа __stdcall. Если используется __fastcall, то указатель на экземпляр и первые 2 параметра передаются через eax, edx, ecx, соответственно. А, вообще, более универсальный способ вы можете подглядеть у компилятора, собрав исполняшку и оттрассировав её.

Указатель на экземпляр объекта всегда болтается в ecx (компилятор MS). Через стек его передает только GCC.
Re[3]: Как из ассемблерной вставки в С++ коде вызвать метод
От: Misha87  
Дата: 26.12.08 13:01
Оценка:
Здравствуйте, bazis1, Вы писали:

Спасибо большое. Проблема еще и в том, чтобы протащить этот указатель на функцию-метод в ассемблерный код. Везде где ни читаю написано, что надо статичемкую функцию юзать, чтобы получить такой указатель и была возможность привести его к void*

Понимаю, что это уже к С++ вопрос относится — но все же, не можетели сказать, как , имея объект и описание класса, получить указатель на функцию-метод

То есть пользовтаель как-то должне вызвать мою SetCallback(void* obj, void* funcPtr)
Вот как пользовталю получить сторой аргумент?
Re[4]: Как из ассемблерной вставки в С++ коде вызвать метод
От: axxie  
Дата: 26.12.08 18:46
Оценка:
Здравствуйте, Misha87, Вы писали:

M>То есть пользовтаель как-то должне вызвать мою SetCallback(void* obj, void* funcPtr)

M>Вот как пользовталю получить сторой аргумент?

То, что вас интересует, выделено полужирным.

#include <iostream>

struct MyClass
{
    void run(int *param) { *param = 2; }
};

typedef void (MyClass::* MethodPointerType)(int *param);

MethodPointerType MethodPointer = &MyClass::run;

int main()
{
    int a = 1;

    std::cout << a << std::endl;
    
    MyClass MyObject;
    (MyObject.*MethodPointer)(&a);

    std::cout << a;

    return 0;
}


Обратите внимание на хитрый синтаксис вызова метода по указателю.
Re[5]: Как из ассемблерной вставки в С++ коде вызвать метод
От: Misha87  
Дата: 26.12.08 18:49
Оценка:
A>MethodPointerType MethodPointer = &MyClass::run;

Это все известно мне. Не хочет компилятор приводить это к void* — попробуйте и убедитесь сами
Re[6]: Как из ассемблерной вставки в С++ коде вызвать метод
От: axxie  
Дата: 26.12.08 19:12
Оценка:
Здравствуйте, Misha87, Вы писали:

M>Это все известно мне. Не хочет компилятор приводить это к void* — попробуйте и убедитесь сами


Видимо я неправильно понял ваш вопрос. Про следующий грязный хак вы уже знаете?
void* ToVoidStar( void* Dummy, ... )
{
    va_list list;
    void*   RetVal;
    
    va_start( list, Dummy );
    RetVal = va_arg( list, void* );
    va_end( list );

    return RetVal;
}
Re[6]: Как из ассемблерной вставки в С++ коде вызвать метод
От: Andrew S Россия http://alchemy-lab.com
Дата: 26.12.08 19:15
Оценка:
A>>MethodPointerType MethodPointer = &MyClass::run;

M>Это все известно мне. Не хочет компилятор приводить это к void* — попробуйте и убедитесь сами


И правильно делает. Поскольку указатель на метод может быть больше чем размер void *. И значительно больше. Подробности — тут:

http://gzip.rsdn.ru/article/cpp/fastdelegate.xml
Автор(ы): Don Clugston
Дата: 27.07.2005
В данной статье предоставлен исчерпывающий материал по указателям на функции-члены, а также приведена реализация делегатов, которые занимают всего две операции на ассемблере.


Да, это все лирика. Собственно, что в этом случае делал бы я. Написал бы простенькую прокси-функцию (не метод, ну, или статический метод), которая бы в качестве аргументов получала только указатель на объект и параметры метода, собственно вызывая его. И извне вызывал бы ее. Это и есть стандартная техника изготовления callback'ов для апи-шных функций.

Удачи.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Как из ассемблерной вставки в С++ коде вызвать метод кла
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 27.12.08 16:29
Оценка: 1 (1) +1
Здравствуйте, Misha87, Вы писали:

M>У меня есть указатель на функцию — метод класса, у меня есть указатель на объект. Как из ассемблерной сатвки вызвать этот метод?


А какой в этом смысл? Почему не закрыть в этом месте скобку ассемблерной вставки, положив напоследок указатель в переменную, вызвать функцию обычным образом, и затем открыть вставку снова? Или вставка вычисляет параметры вызова, сишная функция оптимизирована до упора, и несколько лишних команд качественно испортят ситуацию?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Как из ассемблерной вставки в С++ коде вызвать метод
От: gear nuke  
Дата: 30.12.08 00:31
Оценка:
Здравствуйте, Misha87, Вы писали:

M>Не хочет компилятор приводить это к void* — попробуйте и убедитесь сами


Похоже, используется ключ /Za (ктсати, это вроде как несовместимо в SDK/DDK). Обойти можно, например, так:
template<typename T, typename T2>
static __forceinline
T brute_cast(T2 pf)
{
  STATIC_ASSERT(sizeof(T) == sizeof(T2));
  return *reinterpret_cast<const T*>(&pf);
}

// brute_cast<void*>(p);

В подфоруме С++ можно найти еще варианты.

Однако, исходную задачу наверняка можно решить и без ассемблера.
... << RSDN@Home 1.2.0 alpha 4 rev. 1135>>
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.