0

I have to set up a pointer to a library function (IHTMLDocument2::write) which is a method of the class IHTMLDocument2. (for the curious: i have to hook that function with Detours)

I can't do this directly, because of type mismatch, neither can I use a cast (reinterpret_cast<> which is the "right one" afaik doesn't work)

Here's what I am doing:

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

Thanks for your help!

sth
  • 222,467
  • 53
  • 283
  • 367
zakk
  • 375
  • 1
  • 4
  • 14

2 Answers2

6

The pointer to function has the following type:

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

As you can see, it's qualified with it's class name. It requires an instance of a class to call on (because it is not a static function):

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 */);
GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • OK... Works right... THank you very much! Now I have to create a new function whose type is: HRESULT (WINAPI IHTMLDocument2::*)(SAFEARRAY*) is this possible from outside the class? – zakk Oct 25 '09 at 21:13
4

You need to use a member function pointer. A normal function pointer won't work, because when you call a (non-static) class member function there is an implicit this pointer referring to an instance of the class.

Charles Salvia
  • 52,325
  • 13
  • 128
  • 140
  • +1 for solving my commented problem... but makes me cringe at c++ for introducing another syntax item to learn. what is the point of it? to guarantee encapsulation safety? – San Jacinto Oct 25 '09 at 21:11
  • Member function pointers aren't used that often it seems, but they do have their uses. For example, boost::bind takes advantage of member function pointers so you can do, for example boost::bind(&Foo::somefunction, &instance, arg1, arg2) – Charles Salvia Oct 25 '09 at 21:17
  • 2
    @San: Member function pointers (MFP's) are handled differently from normal functions pointers because they *ARE* different... it's not just syntactic sugar. The size of MFP's are often larger (8 or 12 bytes vs 4 on 32-bit machines), they pass an implicit this pointer, often they call through a small chunk of thunking code rather than directly (so they can possibly invoke virtual functions). So they are both more expensive memory-wise and for CPU-performance (cost to invoke) than a normal function pointer. – Adisak Oct 25 '09 at 21:30
  • They can be particularly useful as callback handlers. Plus, the annoying syntax can be mitigated by using boost::mem_fn or boost::bind. – Charles Salvia Oct 25 '09 at 21:30
  • Thanks, all. A great starting place for me. – San Jacinto Oct 26 '09 at 11:54