Single Instance in COM Class
-
Hi, I have two questions : 1) How would you create a singleton ATL COM Class? (Like when you do a CoCreateInstace for the interface, you always get the same instance of the class) Right now I did a work around of declaring all the data as static variables. I also read about a macro called as DECLARE_SOMETHING_SINGLETON (Not sure about the correct name) 2) I also have some global functions in the same COM Class. These global functions need to access the COM Class member functions. So the global functions need to access only the single instance of this COM Class at any cost. My COM Component is an Out-Proc Win NT Service. The global function code looks like CALLBACK Global_Fn() { //call the class's function CCOMCLASSA *pA = NULL; pA->MemberFunA(); //this is crap piece of code, but due to static vbles, it is working as of now } Any ideas to do all this elegantly? All help will be greatly appreciated. Thanks Misha
-
Hi, I have two questions : 1) How would you create a singleton ATL COM Class? (Like when you do a CoCreateInstace for the interface, you always get the same instance of the class) Right now I did a work around of declaring all the data as static variables. I also read about a macro called as DECLARE_SOMETHING_SINGLETON (Not sure about the correct name) 2) I also have some global functions in the same COM Class. These global functions need to access the COM Class member functions. So the global functions need to access only the single instance of this COM Class at any cost. My COM Component is an Out-Proc Win NT Service. The global function code looks like CALLBACK Global_Fn() { //call the class's function CCOMCLASSA *pA = NULL; pA->MemberFunA(); //this is crap piece of code, but due to static vbles, it is working as of now } Any ideas to do all this elegantly? All help will be greatly appreciated. Thanks Misha
1. You're thinking of the
DECLARE_CLASSFACTORY_SINGLETON
macro. You'd use it like this:class ATL_NO_VTABLE CYourClass : public CComObjectRootEx, public CComCoClass, public IDispatchImpl<Isadfas, &IID_IBlah, &LIBID_ATLPROJLib> { // . // Blah blah // . DECLARE_CLASSFACTORY_SINGLETON(CYourClass) // . // Blah blah // .
2. Given that the class factories have been registered (it's an .EXE server) using the
CoRegisterClassObject
API you can safely and efficiently implement your globals like this:void MyGlobal() { CComPtr<IMyInterface> spInt; if ( SUCCEEDED(spInt.CoCreateInstance(CLSID_YourCLSID)) ) { spInt->YourMethod(); } }
Steve
-
1. You're thinking of the
DECLARE_CLASSFACTORY_SINGLETON
macro. You'd use it like this:class ATL_NO_VTABLE CYourClass : public CComObjectRootEx, public CComCoClass, public IDispatchImpl<Isadfas, &IID_IBlah, &LIBID_ATLPROJLib> { // . // Blah blah // . DECLARE_CLASSFACTORY_SINGLETON(CYourClass) // . // Blah blah // .
2. Given that the class factories have been registered (it's an .EXE server) using the
CoRegisterClassObject
API you can safely and efficiently implement your globals like this:void MyGlobal() { CComPtr<IMyInterface> spInt; if ( SUCCEEDED(spInt.CoCreateInstance(CLSID_YourCLSID)) ) { spInt->YourMethod(); } }
Steve
Thanks Steve :)
-
Thanks Steve :)
I am again into dilemma here. I am sorry, very new to COM programming. The problem is: I have two kinds of functions in my COM class. 1) Functions that are exposed via the interface 2) Internal routines of the COM class which the global functions/main program may need to call So if I am creating a COM Class, does it mean that the only link to my COM Class should be via the interface routines? i.e. all the internal routines which require to be called by the global functions also need to be exposed as interface routines? So what I gather from this is that if somebody wants to access your COM Class (from anywhere, say the winmain routine of your service or some global function in your COM Class itself etc), it has to be via the interface pointer only. Any help greatly appreciated. Thanks & Regards, Misha
-
I am again into dilemma here. I am sorry, very new to COM programming. The problem is: I have two kinds of functions in my COM class. 1) Functions that are exposed via the interface 2) Internal routines of the COM class which the global functions/main program may need to call So if I am creating a COM Class, does it mean that the only link to my COM Class should be via the interface routines? i.e. all the internal routines which require to be called by the global functions also need to be exposed as interface routines? So what I gather from this is that if somebody wants to access your COM Class (from anywhere, say the winmain routine of your service or some global function in your COM Class itself etc), it has to be via the interface pointer only. Any help greatly appreciated. Thanks & Regards, Misha
The easiest way (not pretty to look at) is to make your functions look like this:
void MyGlobal() { CComPtr<IMyInterface> spInt; if ( SUCCEEDED(spInt.CoCreateInstance(CLSID_YourCLSID)) ) { CYourClass* pClass = static_cast<CYourClass*>(spInt.p); pClass->YourMethod(); } }
Steve
-
The easiest way (not pretty to look at) is to make your functions look like this:
void MyGlobal() { CComPtr<IMyInterface> spInt; if ( SUCCEEDED(spInt.CoCreateInstance(CLSID_YourCLSID)) ) { CYourClass* pClass = static_cast<CYourClass*>(spInt.p); pClass->YourMethod(); } }
Steve
-
I think it won't work that way. Maybe (and I'm not sure) only if the COM object is created within the same process. In that case you could do like: CYourClass * pClass = new CYourClass(); instead of creating any com object.
I was assuming that the globals you were talking about where in the COM server - In which case the technique I gave will work. You couldn't just create a new class each time because it wouldn't be a singleton in this case. If the global you're talking about are meant to be in the client then this technique will not work - But in that case the only real solution is to expose the functionality as COM interfaces. Steve
-
1. You're thinking of the
DECLARE_CLASSFACTORY_SINGLETON
macro. You'd use it like this:class ATL_NO_VTABLE CYourClass : public CComObjectRootEx, public CComCoClass, public IDispatchImpl<Isadfas, &IID_IBlah, &LIBID_ATLPROJLib> { // . // Blah blah // . DECLARE_CLASSFACTORY_SINGLETON(CYourClass) // . // Blah blah // .
2. Given that the class factories have been registered (it's an .EXE server) using the
CoRegisterClassObject
API you can safely and efficiently implement your globals like this:void MyGlobal() { CComPtr<IMyInterface> spInt; if ( SUCCEEDED(spInt.CoCreateInstance(CLSID_YourCLSID)) ) { spInt->YourMethod(); } }
Steve
Thanks Stephen, I was looking all over the internet for an answer to this. And to say it was just a macro DECLARE_CLASSFACTORY_SINGLETON.
-
Thanks Stephen, I was looking all over the internet for an answer to this. And to say it was just a macro DECLARE_CLASSFACTORY_SINGLETON.
Glad to be of help. A 2006 post I notice....
Steve