I'm writing a COM server exe using CLSCTX_LOCAL_SERVER as below.
1. COM server:
. Use IDL language to define a interfaceID, classID.
. Call CoRegisterClassObject to register a factory object
2. COM Client.
. Call ::CoGetClassObject(CLSID_CoABC, CLSCTX_LOCAL_SERVER, NULL, IID_IClassFactory, (void **) &pFac);
. hr = pFac->CreateInstance(NULL,interfaceID,(void**)&pObj);
When calling CreateInstance , I only receive error "Interface not registered"
Did you attempt to write it from scratch or did you let the wizard do its thing?
-> I wrote it from scratch.
Is the server registered?
-> Yes. I use CoRegisterClassObject to register a factory object in COM Server EXE.
I tried debug at CObjFactory::CreateInstance( IUnknown *pUnkOuter, REFIID riid, void **ppvObject), I found that it return correct value. But when COM Client receive the result, it fail with "Interface not registered" message.
You could check the registry to see if the interface is registered there.
-> I checked it, But not found.
However, I've registered it by CoRegisterClassObject calling. Besides, In COM server, I catched the CreateInstance calling from COM Client. And it return S_OK. But at COM Client, it shows "Interface not registered"
CoRegisterClassObject registers the class object for a CoClass, not an interface.
You will either have to register the proxy-stub DLL for your interface, or the type library if you're using universal marshalling.
The creation of the object is clearly working, but it doesn't know how to pass the new interface between processes.
To confirm this, create your object with IUnknown rather than your custom interface and see if that succeeds. Then QueryInterface, which should fail (until your sort out the proxy/universal proxy.)
Thanks for your information, I'll investigate what you said. (Do you have a reference link?)
However, I still not understand the reason that when I debug COM Server source code,
it catches successful the CreateInstance calling from COM Client with the exact interface and return success value. But at Client, it receives a different value.
If you are requesting your custom interface when you create an object, then it will know how to create it (you've successfully registered the class factory) but it don't know how to marshall your interface between processes. The error the client (in a different process) is getting is due to the problems marshalling.
Hi Andy,
Thanks for your reply. I tried adding as below
HKEY_CLASSES_ROOT\interface
{My Interface Value}
ProxyStubClsid = ClassID
ProxyStubClsid32 = ClassID.
But it fails.
Here is my COM Server structure, please take a look and give me some suggestion.
class CMyFactory : public IClassFactory
{
};
class CMyObj : public IUnknown
{
-----class XSubClass : public IMyInterface
-----{
-----}m_subClass;
-----friend class CMyObj;
}
===============
At ComClient, I call CreateInstance with IMyInterface.
Check out the documentation on midl. When you process your idl file you will generate the required proxy-stub DLL code, and typelib if you want it. You need to register this DLL.
ProxyStubClsid32 is the CLSID of the proxy-stub, just to be clear.
The proxy-stub is a DLL (actually, it can be two - a proxy and stub - but they are usually combined). It's loaded once by the client app and again by the COM local server, and handles the inter-process calls. The COM local server cannot act as a proxy for any of the interfaces it uses.