I'm in the process of implementing a COM server in an EXE file. To be precise, I'm adding a COM interface to an existing application. with the ultimate goal of automating the application.
The first component and an interface (with a single method so far) are basically in place. I can build an in-proc server in a DLL and successfully obtain an interface pointer and call the method. This was done as a first step since I'm only just learning. I won't need the DLL later; it just serves as proof of concept that my component and interface are basically ok.
Then I built an out-of-process server in an EXE. I have got to the point where I can call CoCreateInstance()
from the client, and the EXE is started, registers its factory, and the factory creates an instance of the component. CoCreateInstance
returns S_OK and the client receives an interface pointer that is not NULL.
The problem occurs when I call the interface's method.
Run-Time Check
Failure #0 - The value of ESP was not properly saved across a
function call. This is usually a result of calling a function
declared with one calling convention with a function pointer declared
with a different calling convention.
.I'm absolutely aware that methods in a COM interface must use __stdcall
, and I have checked several times that it's not missing. Besides, the implementation of the component (C++) derives from the interface generated by MIDL. So the interface's header file has the correct calling convention, and if the component's header file did not, the compiler would complain about the override differing.
Since the breakpoint is not even hit, my gut feeling is that something is fundamentally wrong with the local procedure call, along the lines of the vtbl not being set up correctly. Does anyone have a suggestion what could be causing the observed behaviour? Any tips on how to debug the proxy/stub code?
EDIT:
In response to WhozCraig, here the IDL file:
import "unknwn.idl";
// Interface IMyApp1
[
object,
uuid(440EA043-DF6D-4df9-963D-7660BBA829EF),
helpstring("IMyApp1 Interface"),
pointer_default(unique)
]
interface IMyApp1: IUnknown
{
HRESULT ShowAboutBox(void);
}
I found the problem. It's quite an embarrassing mistake, but interesting to know that it leads to the observed effect, so I'll post it here in case someone else has the same problem.
The client was doing
HdResult = CoCreateInstance(
sClassIdApp,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IUnknown, // Oops...
(void**) &pInterface);
pInterface->ShowAboutBox();
instead of
HdResult = CoCreateInstance(
sClassIdApp,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IMyApp1,
(void**) &pInterface);
pInterface->ShowAboutBox();
Duh...