Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. COM
  4. Single Instance in COM Class

Single Instance in COM Class

Scheduled Pinned Locked Moved COM
c++comhelpquestion
9 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    misha_grewal
    wrote on last edited by
    #1

    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

    S 1 Reply Last reply
    0
    • M misha_grewal

      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

      S Offline
      S Offline
      Stephen Hewitt
      wrote on last edited by
      #2

      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

      M S 2 Replies Last reply
      0
      • S Stephen Hewitt

        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

        M Offline
        M Offline
        misha_grewal
        wrote on last edited by
        #3

        Thanks Steve :)

        M 1 Reply Last reply
        0
        • M misha_grewal

          Thanks Steve :)

          M Offline
          M Offline
          misha_grewal
          wrote on last edited by
          #4

          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

          S 1 Reply Last reply
          0
          • M misha_grewal

            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

            S Offline
            S Offline
            Stephen Hewitt
            wrote on last edited by
            #5

            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

            G 1 Reply Last reply
            0
            • S Stephen Hewitt

              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

              G Offline
              G Offline
              Gizzo
              wrote on last edited by
              #6

              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.

              S 1 Reply Last reply
              0
              • G Gizzo

                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.

                S Offline
                S Offline
                Stephen Hewitt
                wrote on last edited by
                #7

                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 Reply Last reply
                0
                • S Stephen Hewitt

                  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

                  S Offline
                  S Offline
                  subzero_strike
                  wrote on last edited by
                  #8

                  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.

                  S 1 Reply Last reply
                  0
                  • S subzero_strike

                    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.

                    S Offline
                    S Offline
                    Stephen Hewitt
                    wrote on last edited by
                    #9

                    Glad to be of help. A 2006 post I notice....

                    Steve

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups