Re: Лямбду в WinAPI
От: jyuyjiyuijyu  
Дата: 28.03.11 11:32
Оценка:
еще такое бывает )))
по мотивам http://www.gamedev.ru/code/forum/?id=85183&page=2
#include <windows.h>
#include <stdio.h>

typedef unsigned __int32 uint32;
typedef unsigned __int16 uint16;
typedef unsigned __int8   uint8;

#include <PshPack1.h>
struct thunk
{
  uint16 a; uint8 b; uint32 c; void* param;
  uint8 d; void* pfn; uint16 e;
  //---------------------
  uint16 aa; uint8 bb; uint32 cc; void* paramm;
  uint8 dd; void* pfnn; uint16 ee;
};
#include <PopPack.h>

template<class ArgType1>
struct objCallback1
{
    void *f;
    ArgType1 a1;
    thunk &t;
    objCallback1(void *f, ArgType1 a1):f(f),t(*new thunk)
    {
        typedef char buf[sizeof(ArgType1) <= sizeof(void*) ? 1 : 0];
        objCallback1::a1 = a1;
    }
    template<class Ret_t>
    operator Ret_t *()
    {
        return join<Ret_t>();
    }
    template<class Ret_t>
    Ret_t * join()
    {
        t.a = 0x34FF; t.b = 0x24;  t.c = 0x042444C7;  t.param = (void*)a1;
        t.d = 0xB8; t.pfn = f; t.e = 0xE0FF;
        //------------------------
        t.aa = 0x34FF; t.bb = 0x24;  t.cc = 0x042444C7;  t.paramm = (void*)&t;
        t.dd = 0xB8; t.pfnn = free_join; t.ee = 0xE0FF;
        atexit((void(*)())((char*)&t + 18));
        return (Ret_t *)&t;
    }
    /*
     testlinkage.exe!objCallback1<unsigned int>::free_join(void * mem=0x00356d00)  Line 48    C++
     msvcr90d.dll!doexit(int code=0x00000000, int quick=0x00000000, int retcaller=0x00000000)  Line 591    C
     msvcr90d.dll!exit(int code=0x00000000)  Line 412 + 0xd bytes    C
     testlinkage.exe!__tmainCRTStartup()  Line 595    C
     testlinkage.exe!mainCRTStartup()  Line 399    C
     kernel32.dll!_BaseProcessStart@4()  + 0x23 bytes    
    */
    static void __stdcall free_join(void *mem)
    {
        delete mem;
    }
};

template<class ArgType1>
objCallback1<ArgType1> Join(void *f, ArgType1 a1)
{
    return objCallback1<ArgType1>(f, a1);
}

VOID CALLBACK 
MyTimerProc(void* userdata, HWND hwnd, UINT uMsg,  UINT idEvent,  DWORD dwTime)
{
    printf("User data @ 0x%p\n", userdata );
}

int main()
{
    SetTimer(0, 0, 1000, Join(MyTimerProc, 0xdeadc0de));

    MSG msg;
    int ecx = 0;
    while(ecx++ < 3 && GetMessage(&msg, NULL, 0, 0))
        DispatchMessage(&msg);
}

можно сделать доступным от 1 и более
параметров для склейки ограничение та к кому клеим
должна быть с __stdcall соглашением
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.