Click here to Skip to main content
15,914,444 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
GeneralRe: Edit Box Variables Pin
13-Dec-01 16:05
suss13-Dec-01 16:05 
GeneralRe: Edit Box Variables Pin
Cam13-Dec-01 18:35
Cam13-Dec-01 18:35 
Generalstupid toolbar question Pin
jafrazee13-Dec-01 8:46
jafrazee13-Dec-01 8:46 
GeneralRe: stupid toolbar question Pin
Prem Kumar13-Dec-01 10:09
Prem Kumar13-Dec-01 10:09 
GeneralRe: stupid toolbar question Pin
jafrazee13-Dec-01 10:15
jafrazee13-Dec-01 10:15 
General__thiscall conversions... Pin
BlackSmith13-Dec-01 7:35
BlackSmith13-Dec-01 7:35 
GeneralRe: __thiscall conversions... Pin
Michael Dunn13-Dec-01 7:43
sitebuilderMichael Dunn13-Dec-01 7:43 
GeneralRe: __thiscall conversions... Pin
Joaquín M López Muñoz13-Dec-01 22:35
Joaquín M López Muñoz13-Dec-01 22:35 
Well, if you're in desperate need of treating a pointer to member function as a regular pointer to function, and you can afford changing the calling convention of your member function, then there is a tricky, heavily non-portable workaround: Consider the following class:
class A
{
  public:
    int __cdecl f(int a_){a=a_; return a+1;}
  private:
    int a;
};
From the point of view of the compiler, A::f is called like a regular function having a first hidden parameter that provides the this pointer. That is, the types PMEMBFUNCTION and PFUNCTION, defined as
typedef int (__cdecl A::* PMEMBFUNCTION)(int);
typedef int (__cdecl    * PFUNCTION)    (A*,int);
are equivalent in the sense that the compiler generates the same code to execute calls for them. Alas, this kind of equivalence does not allow us to force a cast between the types. So the snippet of code
A             a;
PMEMBFUNCTION pmf=A::f;
PFUNCTION     pf=reinterpret_cast<PFUNCTION>(pmf);
does not compile: from the compiler point of view, the types involved are wildly disimilar. Tricks like trying an intermediate cast to void * do not work either.
Not all hope is lost, nevertheless. We can use a last resort to force the casting. This struct
struct caster{
  union{
    PMEMBFUNCTION pmf;
    PFUNCTION     pf;
  };
};
implicitly does the casting for us: the union allows us to store a PMEMBFUNCTION and retrieve a PFUNCTION. This kind of "casting" is even stronger than the allmighty reinterpret_cast!
So here's a complete program that shows how to call A::f as a regular function, providing the extra this parameter. I hope the technique is clear after this exposition.
#include <iostream>

using namespace std;

class A
{
  public:
    int __cdecl f(int a_){a=a_; return a+1;}
  private:
    int a;
};

typedef int (__cdecl A::* PMEMBFUNCTION)(int);
typedef int (__cdecl    * PFUNCTION)    (A*,int);

struct caster{
  union{
    PMEMBFUNCTION pmf;
    PFUNCTION     pf;
  };
};

int main(void)
{
  A         a;
  caster    c; c.pmf=A::f; // put the pointer to memb function in...
  PFUNCTION pf=c.pf;       // and pull the pointer to function out!
  
  cout<<pf(&a,666)<<endl;  // &a is the extra "this" pointer
  
  return 0;
}
One major drawback of this trick (apart from being scandalously non-portable) is that the member function has to be declared with the __cdecl calling convention. Why is this so? Well, if no calling convention is specified, the compiler uses the default __thiscall. In this calling convention, normal parameters are passed to the member function as in __cdecl, but the this pointer is stored in register ECX. You cannot simulate this behavior when calling a regular function, unless you use some assembly code.
Also, this definitely does not work with virtual member functions.

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
GeneralSendInput delay :( Pin
Goa13-Dec-01 7:26
Goa13-Dec-01 7:26 
GeneralRe: SendInput delay :( Pin
Michael Dunn13-Dec-01 7:32
sitebuilderMichael Dunn13-Dec-01 7:32 
GeneralLosing ptr to CDocument in SDI Pin
Mark Donkers13-Dec-01 7:24
Mark Donkers13-Dec-01 7:24 
GeneralRe: Losing ptr to CDocument in SDI Pin
Masaaki Onishi13-Dec-01 11:02
Masaaki Onishi13-Dec-01 11:02 
GeneralRe: Losing ptr to CDocument in SDI Pin
Mark Donkers13-Dec-01 12:25
Mark Donkers13-Dec-01 12:25 
GeneralEntry-Points :) Pin
Marc Richarme13-Dec-01 7:13
Marc Richarme13-Dec-01 7:13 
GeneralRe: Entry-Points :) Pin
Rick York13-Dec-01 8:08
mveRick York13-Dec-01 8:08 
GeneralRe: Entry-Points :) Pin
Carlos Antollini13-Dec-01 8:28
Carlos Antollini13-Dec-01 8:28 
GeneralRe: Entry-Points :) Pin
Marc Richarme13-Dec-01 11:25
Marc Richarme13-Dec-01 11:25 
GeneralVisual Studio problems - please help! Pin
Cam13-Dec-01 6:55
Cam13-Dec-01 6:55 
GeneralRe: Visual Studio problems - please help! Pin
Alvaro Mendez13-Dec-01 11:22
Alvaro Mendez13-Dec-01 11:22 
GeneralRe: Visual Studio problems - please help! Pin
Prem Kumar13-Dec-01 12:05
Prem Kumar13-Dec-01 12:05 
GeneralRe: Visual Studio problems - please help! Pin
Cam13-Dec-01 12:32
Cam13-Dec-01 12:32 
QuestionHow do I add a bitmap to a property sheet Pin
PaulJ13-Dec-01 5:55
PaulJ13-Dec-01 5:55 
AnswerRe: How do I add a bitmap to a property sheet Pin
Joaquín M López Muñoz13-Dec-01 6:43
Joaquín M López Muñoz13-Dec-01 6:43 
GeneralMenu Item appears Grayed in MFC Pin
13-Dec-01 5:53
suss13-Dec-01 5:53 
GeneralRe: Menu Item appears Grayed in MFC Pin
Joaquín M López Muñoz13-Dec-01 6:14
Joaquín M López Muñoz13-Dec-01 6:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.