I need to write code that calls an external function that can be either stdcall call or cdecl in a 32bit windows application.
My code, the caller, can't know in advance which of these its going to be.
Right now, if I try to call a cdecl function from a call site that was defined as stdcall, I get a checkEsp exception dialog, and I'm guessing that's there for a good reason.
Is there any way to do it?
It can be done following way:
mov esi, esp
push arg3
push arg2
push arg1
call [SomeExternalProc]
mov esp, esi ; now the stack is always properly cleaned
The external procedure will preserve esi. Or you can use any other register preserved by the external procedure or even memory variable - local or global.
Good, the order of the arguments is the same for CDECL and STDCALL - in reverse order. (Left-most arg at the lowest address.) So they're compatible except for where ESP points on return. Both conventions agree on which registers are call-preserved vs. call-clobbered.