2009-10-25 4 views
0

Мне нужно настроить указатель на библиотечную функцию (IHTMLDocument2::write), которая является методом класса IHTMLDocument2. (для любопытных: я должен подключить эту функцию с помощью Detours)C++ - указатель на метод класса

Я не могу сделать это напрямую, из-за несоответствия типа, я также не могу использовать литой (reinterpret_cast<>, который является «правильным», afaik не работа)

Вот что я делаю:

HRESULT (WINAPI *Real_IHTMLDocument2_write)(SAFEARRAY *) = &IHTMLDocument2::write 

Спасибо за вашу помощь!

+0

Было моим опытом, что для указания метода класса этот метод должен быть статическим. –

+0

@San Jacinto. Это не правда. У вас могут быть указатели на обычные методы. –

ответ

6

Указатель функции имеет следующий вид:

HRESULT (WINAPI IHTMLDocument2::*)(SAFEARRAY*) 

Как вы можете видеть, это квалифицируется с его именем класса. Для этого требуется экземпляр класса для вызова (потому что он не является статической функцией):

typedef HRESULT (WINAPI IHTMLDocument2::*DocumentWriter)(SAFEARRAY*); 

DocumentWriter writeFunction = &IHTMLDocument2::write; 

IHTMLDocument2 someDocument = /* Get an instance */; 
IHTMLDocument2 *someDocumentPointer = /* Get an instance */; 

(someDocument.*writefunction)(/* blah */); 
(someDocumentPointer->*writefunction)(/* blah */); 
+0

ОК ... Работает правильно ... Ударьте! Теперь я должен создать новую функцию, тип которого: HRESULT (WINAPI IHTMLDocument2 :: *) (* SAFEARRAY) это возможно из-за пределов класса? – zakk

4

Вам необходимо использовать member function pointer. Нормальный указатель функции не будет работать, потому что, когда вы вызываете (нестатический) элемент-член класса, существует неявный указатель this, ссылающийся на экземпляр класса.

+0

+1 для решения моей прокомментированной проблемы ... но заставляет меня съеживаться на C++ для введения другого элемента синтаксиса для изучения. в чем смысл? гарантировать безопасность инкапсуляции? –

+0

Указатели функции-функции не используются, что часто кажется, но они действительно используют их. Например, boost :: bind использует преимущества указателей на функции-члены, например, boost :: bind (& Foo :: somefunction, & instance, arg1, arg2) –

+2

@San: указатели на функции функций (MFP) обрабатываются по-разному нормальные указатели функций, потому что они * ARE * разные ... это не просто синтаксический сахар. Размер MFP часто больше (8 или 12 байт против 4 на 32-разрядных машинах), они пропускают неявный этот указатель, часто они вызывают небольшой фрагмент кода thunking, а не напрямую (поэтому они могут вызывать виртуальные функции) , Таким образом, они более дорогие по размеру памяти и для производительности процессора (стоимость вызова), чем обычный указатель на функцию. – Adisak