Click here to Skip to main content
Click here to Skip to main content

Pass Class Method as Static function to API Calls

, 12 Mar 2002
Rate this:
Please Sign up or sign in to vote.
Pass Class Methods to API Calls where Static Functions are required using CThunk class

Introduction

A number of times we need to define static functions in a class to pass them to API Calls like Window Proc, Thread Proc, etc. Typically we define a static/global function and pass this as one parameter and recast that parameter into object again. In these cases, we can define a thunk that generates the Static Procedure at runtime, and pass the generated Proc to the API Function. All we need to set this correctly at runtime and jump to required address.

Code listing

The following class CThunk does the same thing.

/*
Thunk Class 
Parameters:

F1:   Static Proc
F2:   Class function
T1 :  Class

// Function Types F1 & F2 should have same parameters 
// and return type otherwise stack corruption will occur

*/

#if defined(_M_IX86)
#pragma pack(push,1)

template <typename F1,typename F2, typename T1>
class CThunk
{
public:
    struct _ProcThunk
    {
        BYTE m_movcx;          
        DWORD m_pThis;
        BYTE    m_jmp;          // jmp WndProc
        DWORD   m_relproc;      // relative jmp
    };

    _ProcThunk thunk;

    void Init(F2 proc, T1 * pClass)
    {
        //make sure that 'this' is in ecx pointer
        // otherwsie code does not work
#ifdef _DEBUG
        long  pthis;
        _asm  { mov         dword ptr [pthis],ecx }; 
        assert(pthis == (long) this);
#endif
        // put values
        thunk.m_movcx = 0xB9;  //B9
        thunk.m_pThis= (DWORD)pClass;
        thunk.m_jmp = 0xe9;
        thunk.m_relproc = 
            *((int *) &proc) - ((int)this+sizeof(_ProcThunk));

        // write block from data cache and 
        // flush from instruction cache
        FlushInstructionCache(GetCurrentProcess(), 
            &thunk, sizeof(thunk));
    }

    F1 GetStaticProc()
    {
        return reinterpret_cast<F1> (&thunk);
    }
};
#pragma pack(pop)
#else
#error Only X86 supported
#endif

Usage

The following code shows the usage of CThunk class for threads Proc. This class can be used in other places where Static procs are required. In this code CThunk class is used to create a thunk for the _beginthread API Call.

//Test Thread class

typedef void( __cdecl *THREADPROC )( void * );

class CThreadTest
{
protected:
    typedef LRESULT (CThreadTest::*FTN)
        (LPVOID lpThreadParameter);

    // THREADPROC & FTN have same signature
    CThunk<THREADPROC,FTN,CThreadTest> m_th; 

    HANDLE m_hThread;


public:
    //data
    int m_y;
    CThreadTest()
    {
        //Intialize the Thunk
        m_th.Init(CThreadTest::ThreadFunction,this);

    }
    LRESULT ThreadFunction(LPVOID lpThreadParameter)
    {
        int ntime =(int) lpThreadParameter;
        printf("%d",m_y); // this pointer is set correctly
        Sleep(ntime);
        return 0;
    }

    BOOL Create (int nSleeptime)
    {
        //Get Static Proc
        THREADPROC tp =m_th.GetStaticProc();

        // pass proc to  _beginthread
        m_hThread = (HANDLE)_beginthread(tp, 0,
            (LPVOID)nSleeptime);
        return TRUE;
    }

    void WaitForThread()
    {
        WaitForSingleObject(m_hThread,INFINITE);

    }


};



int main(int argc, char* argv[])
{
    CThreadTest t1;
    t1.m_y=100;

    t1.Create(1000);



    t1.WaitForThread();


    return 0;
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Deepak Khajuria
Web Developer
United States United States
Programming in MFC/ATL for 2-3 years.

Comments and Discussions

 
Generalsomething similar Pinmemberreal name12-Mar-02 22:14 

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

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

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 13 Mar 2002
Article Copyright 2002 by Deepak Khajuria
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid