Sorry за оффтопик. Вопрос такой:
можно ли в VC6.0 объявить функцию как паскалевскую (параметры пихаются в стек слева направо)?
ну или хотя бы как обойти это?
З.Ы. использование PASCAL не предлагать — это __stdcall (параметры заносятся справа налево).
Здравствуйте, Yarrr, Вы писали:
Y>Sorry за оффтопик. Вопрос такой:
Y>можно ли в VC6.0 объявить функцию как паскалевскую (параметры пихаются в стек слева направо)?
Y>ну или хотя бы как обойти это?
Y>З.Ы. использование PASCAL не предлагать — это __stdcall (параметры заносятся справа налево).
А для чего это Вам нужно? Если Вы пишете на C[++] функцию, которая будет вызываться из паскалевского кода, можно использовать __stdcall и просто объявить аргументы в обратном порядке.

Вроде должно работать.
А>А для чего это Вам нужно?
— Перехват вызова метода СОМ объекта (DirectX) в чужой проге. (как ни странно, но при вызове параметры пихаются слева направо)
А>А Если Вы пишете на C[++] функцию, которая будет вызываться из паскалевского кода, можно использовать __stdcall и просто объявить аргументы в обратном порядке.
А>Вроде должно работать.
— не, такой номер не проходит
Здравствуйте, Yarrr, Вы писали:
Y>можно ли в VC6.0 объявить функцию как паскалевскую (параметры пихаются в стек слева направо)?
Y>ну или хотя бы как обойти это?
Y>З.Ы. использование PASCAL не предлагать — это __stdcall (параметры заносятся справа налево).
Могу придумать только такую фичу
int foo(int x, int y, int z);
int foo_thunk(int z, int y, int x) { return foo(x, y, z); }
Можно сделать шаблон
template<class R, class P1, class P2>
struct pascalthunk2
{
typedef R(_stdcall*stdcall_func)(P1,P2);
typedef R(_stdcall*pascal_func)(P2,P1);
// обращатели
static R s2p(pascal_func f, P1 p1, P2 p2) { return f(p2,p1); }
static R p2s(stdcall_func f, P2 p2, P1 p1) { return f(p1,p2); }
template<stdcall_func f>
struct thunk
{
static R _stdcall code(P2 p2, P1 p1) { return f(p1,p2); }
};
};
/////////////////////////
// пример
// исходная функция (обязательно extern linkage)
extern bool _stdcall hello(char x, int y)
{
cout << "x=" << x << ", y=" << y << endl;
return true;
}
// клиенты
// с правильными типами
void indirect( pascalthunk2<bool,char,int>::pascal_func func )
{
pascalthunk2<bool,char,int>::s2p(func, 'q', 10);
}
// просто ожидающая pascal
void indirect_void(void* func)
{
_asm {
push 'q'
push 10
call dword ptr[func]
}
}
void main()
{
indirect( pascalthunk2<bool,char,int>::thunk<hello>::code );
}
Здравствуйте, Yarrr, Вы писали:
[]
Y> — Перехват вызова метода СОМ объекта (DirectX) в чужой проге. (как ни странно, но при вызове параметры пихаются слева направо)
[]
Тогда Вам паскальная конвенция не нужна. COM-методы всегда используют конвенцию, заданную макросом STDMETHODCALLTYPE, который определен как stdcall:
/* basetypes.h */
....
#define STDMETHODCALLTYPE __stdcall
....
#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method
....
Для примера (если не верите

):
/* ddraw.h */
DECLARE_INTERFACE_( IDirectDraw, IUnknown )
{
/*** IUnknown methods ***/
STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE;
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
STDMETHOD_(ULONG,Release) (THIS) PURE;
/*** IDirectDraw methods ***/
STDMETHOD(Compact)(THIS) PURE;
STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE;
......