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. How to delete a COM object

How to delete a COM object

Scheduled Pinned Locked Moved COM
comtestingcsharpc++beta-testing
6 Posts 2 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.
  • A Offline
    A Offline
    AmitGG
    wrote on last edited by
    #1

    I have a C# (managed code) DLL and I am accessing this DLL's functions from C++ (unmanaged code) using COM. I create a COM object with CoCreateInstance function. Then I do work on this object. After that I call Release() function on this object. But after calling Release() function the object is not destroyed automatically. After calling Release function I called some more functions on this object and all those calls were successful. I called CoCreateInstance only once and there is only one reference of this object in my code. I also checked the return value of Release function call which is ZERO which shows the reference count of the object is ZERO and it should automatically destroy the object as soon as the reference count becomes ZERO. But in my case the object is not destroyed. Actually in my project work I have to create and destroy the COM object many times (1000-2000). So in each iteration the memory size is increasing and after some iteration it becomes more than 1 GB and fills all the page file space and the program hangs. Could Anybody suggest me how to delete the COM object. The code I am using is following : #include #include #include #include #import "mscorlib.tlb" raw_interfaces_only #import "Flowmaster.Automation.Gui.tlb" no_namespace named_guids #import "Flowmaster.Automation.Analysis.tlb" no_namespace named_guids class CFDlinkDoc { IFM2_AnalysisControl* m_pAnalCntrlv7; BSTR sDataSource; BSTR sDataBase; BSTR sProject; BSTR sUserName; BSTR sPassword; BSTR Project; BSTR NetworkName; BSTR Description; BSTR Owner; int ResultID; public: CFDlinkDoc(); void func1(); }; CFDlinkDoc::CFDlinkDoc() { m_pAnalCntrlv7 = NULL; sDataSource = L"pcpune26"; sDataBase = L"FM100206"; sProject = L"Flowmaster"; sUserName = L"Admin"; sPassword = L""; Project = L"Flowmaster"; NetworkName = L"AmitG"; Description = L"Hi, COM testing From C++"; Owner = L"AG"; } void CFDlinkDoc::func1() { HRESULT hr = CoInitialize(NULL); hr = CoCreateInstance(__uuidof(FM2_AnalysisControl) ,NULL, CLSCTX_INPROC_SERVER, __uuidof(IFM2_AnalysisControl), reinterpret_cast(&m_pAnalCntrlv7)); long lP= m_pAnalCntrlv7->DatabaseLogin(sDataSource, sDataBase, sProject, sUserName, sPassword); m_pAnalCntrlv7->PutProjectName(Project); m_pAnalCntrlv7->PutNetworkName(NetworkName); m_pAnalCntrlv7->PutDescription(Description); m_pAnalCntrlv7->PutOwnername(Owner); m_pAnalCntrlv7->PutAnalysisType(_T

    M 1 Reply Last reply
    0
    • A AmitGG

      I have a C# (managed code) DLL and I am accessing this DLL's functions from C++ (unmanaged code) using COM. I create a COM object with CoCreateInstance function. Then I do work on this object. After that I call Release() function on this object. But after calling Release() function the object is not destroyed automatically. After calling Release function I called some more functions on this object and all those calls were successful. I called CoCreateInstance only once and there is only one reference of this object in my code. I also checked the return value of Release function call which is ZERO which shows the reference count of the object is ZERO and it should automatically destroy the object as soon as the reference count becomes ZERO. But in my case the object is not destroyed. Actually in my project work I have to create and destroy the COM object many times (1000-2000). So in each iteration the memory size is increasing and after some iteration it becomes more than 1 GB and fills all the page file space and the program hangs. Could Anybody suggest me how to delete the COM object. The code I am using is following : #include #include #include #include #import "mscorlib.tlb" raw_interfaces_only #import "Flowmaster.Automation.Gui.tlb" no_namespace named_guids #import "Flowmaster.Automation.Analysis.tlb" no_namespace named_guids class CFDlinkDoc { IFM2_AnalysisControl* m_pAnalCntrlv7; BSTR sDataSource; BSTR sDataBase; BSTR sProject; BSTR sUserName; BSTR sPassword; BSTR Project; BSTR NetworkName; BSTR Description; BSTR Owner; int ResultID; public: CFDlinkDoc(); void func1(); }; CFDlinkDoc::CFDlinkDoc() { m_pAnalCntrlv7 = NULL; sDataSource = L"pcpune26"; sDataBase = L"FM100206"; sProject = L"Flowmaster"; sUserName = L"Admin"; sPassword = L""; Project = L"Flowmaster"; NetworkName = L"AmitG"; Description = L"Hi, COM testing From C++"; Owner = L"AG"; } void CFDlinkDoc::func1() { HRESULT hr = CoInitialize(NULL); hr = CoCreateInstance(__uuidof(FM2_AnalysisControl) ,NULL, CLSCTX_INPROC_SERVER, __uuidof(IFM2_AnalysisControl), reinterpret_cast(&m_pAnalCntrlv7)); long lP= m_pAnalCntrlv7->DatabaseLogin(sDataSource, sDataBase, sProject, sUserName, sPassword); m_pAnalCntrlv7->PutProjectName(Project); m_pAnalCntrlv7->PutNetworkName(NetworkName); m_pAnalCntrlv7->PutDescription(Description); m_pAnalCntrlv7->PutOwnername(Owner); m_pAnalCntrlv7->PutAnalysisType(_T

      M Offline
      M Offline
      mbue
      wrote on last edited by
      #2

      Your code seems to be ok. But it is possible that the database server add's a refcount to your interface. Therefore uninitialize your interface (calls like: close() uninitialize() or some like that). If all dependencies are release your interface will be destroyed finally. By the way you should never delete an interface (delete m_pAnalCntrlv7;).

      A 1 Reply Last reply
      0
      • M mbue

        Your code seems to be ok. But it is possible that the database server add's a refcount to your interface. Therefore uninitialize your interface (calls like: close() uninitialize() or some like that). If all dependencies are release your interface will be destroyed finally. By the way you should never delete an interface (delete m_pAnalCntrlv7;).

        A Offline
        A Offline
        AmitGG
        wrote on last edited by
        #3

        hi mbue, Thank you very much for responding. You are right that I should never delete a interface pointer (delete m_pAnalCntrlv7;). I am not doing it. You say that there is a possibility that database server adds a refcount to my COM object. Yes, there may be a possibility. I have got another very simple code and I have not to use any database in that. But I am still getting the same problem in that code also. I am goofed up trying it. Can you (or anybody else) suggest me any other reasons why it is happening to me? Many heartiest Thanks in Advance :( Amit -- modified at 5:21 Tuesday 28th February, 2006

        M 1 Reply Last reply
        0
        • A AmitGG

          hi mbue, Thank you very much for responding. You are right that I should never delete a interface pointer (delete m_pAnalCntrlv7;). I am not doing it. You say that there is a possibility that database server adds a refcount to my COM object. Yes, there may be a possibility. I have got another very simple code and I have not to use any database in that. But I am still getting the same problem in that code also. I am goofed up trying it. Can you (or anybody else) suggest me any other reasons why it is happening to me? Many heartiest Thanks in Advance :( Amit -- modified at 5:21 Tuesday 28th February, 2006

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

          here comes a very small demonstration how COM works: // client app void CFDlinkDoc::func1() { HRESULT hr = CoInitialize(0); hr = CoCreateInstance(__uuidof(FM2_AnalysisControl) ,0, CLSCTX_INPROC_SERVER, __uuidof(IFM2_AnalysisControl), &m_pAnalCntrlv7); if(S_OK==hr) { m_pAnalCntrlv7->Release(); // m_pAnalCntrlv7->_ref == 0 } CoUninitialize(); } // system call (very abstract) HRESULT CoCreateInstance(REFCLSID rclsid,LPUNKNOWN pout,DWORD dwClsContext,REFIID riid,LPVOID* ppv) { char dll[MAX_PATH]; // find the module in the registry identified by __uuidof(FM2_AnalysisControl) HINSTANCE hi = LoadLibrary(dll); LPFNGETCLASSOBJECT fn=(LPFNGETCLASSOBJECT)(hi?GetProcAddress(h,"DllGetClassObject"):0); if(fn) { IClassFactory* fac; HRESULT hr; if(S_OK==fn(IID_NULL,riid,(void**)ppv)) return S_OK; if(S_OK!=fn(IID_NULL,IID_IClassFactory,(void**)&fac)) return E_NOINTERFACE; hr = fac->CreateInstance(pout,riid,(void**)ppv); fac->Release(); return hr; } return E_FAIL; } // server dll class iAnalysisControl : public IAnalysisControl { public: // IUnknown virtual HRESULT __stdcall QueryInterface(REFIID riid,void** ppv) { if(riid==__uuidof(IFM2_AnalysisControl)) return *(IAnalysisControl**)ppv=this,AddRef(),S_OK; if(riid==IID_IUnknown) return *(IUnknown**)ppv=this,AddRef(),S_OK; return E_NOINTERFACE; } virtual unsigned long __stdcall AddRef(){ return ++_ref; } virtual unsigned long __stdcall Release(){ if(!--_ref){ delete this; return 0; } return _ref; } // iAnalysisControl iAnalysisControl(){ _ref=1; } ~iAnalysisControl(){ ASSERT(!_ref); } long _ref; }; HRESULT FAR PASCAL DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID* ppv) { if(riid==__uuidof(IFM2_AnalysisControl)) { iAnalysisControl* me = new iAnalysisControl; return me?*(IAnalysisControl**)ppv=me,S_OK:E_OUTOFMEMORY; } return E_NOINTERFACE; } Debug through the code and you can see whats wrong in your modules. In this example the external interface refcount goes to zero when you call Release(). Sorry for the vanished tabs.

          A 1 Reply Last reply
          0
          • M mbue

            here comes a very small demonstration how COM works: // client app void CFDlinkDoc::func1() { HRESULT hr = CoInitialize(0); hr = CoCreateInstance(__uuidof(FM2_AnalysisControl) ,0, CLSCTX_INPROC_SERVER, __uuidof(IFM2_AnalysisControl), &m_pAnalCntrlv7); if(S_OK==hr) { m_pAnalCntrlv7->Release(); // m_pAnalCntrlv7->_ref == 0 } CoUninitialize(); } // system call (very abstract) HRESULT CoCreateInstance(REFCLSID rclsid,LPUNKNOWN pout,DWORD dwClsContext,REFIID riid,LPVOID* ppv) { char dll[MAX_PATH]; // find the module in the registry identified by __uuidof(FM2_AnalysisControl) HINSTANCE hi = LoadLibrary(dll); LPFNGETCLASSOBJECT fn=(LPFNGETCLASSOBJECT)(hi?GetProcAddress(h,"DllGetClassObject"):0); if(fn) { IClassFactory* fac; HRESULT hr; if(S_OK==fn(IID_NULL,riid,(void**)ppv)) return S_OK; if(S_OK!=fn(IID_NULL,IID_IClassFactory,(void**)&fac)) return E_NOINTERFACE; hr = fac->CreateInstance(pout,riid,(void**)ppv); fac->Release(); return hr; } return E_FAIL; } // server dll class iAnalysisControl : public IAnalysisControl { public: // IUnknown virtual HRESULT __stdcall QueryInterface(REFIID riid,void** ppv) { if(riid==__uuidof(IFM2_AnalysisControl)) return *(IAnalysisControl**)ppv=this,AddRef(),S_OK; if(riid==IID_IUnknown) return *(IUnknown**)ppv=this,AddRef(),S_OK; return E_NOINTERFACE; } virtual unsigned long __stdcall AddRef(){ return ++_ref; } virtual unsigned long __stdcall Release(){ if(!--_ref){ delete this; return 0; } return _ref; } // iAnalysisControl iAnalysisControl(){ _ref=1; } ~iAnalysisControl(){ ASSERT(!_ref); } long _ref; }; HRESULT FAR PASCAL DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID* ppv) { if(riid==__uuidof(IFM2_AnalysisControl)) { iAnalysisControl* me = new iAnalysisControl; return me?*(IAnalysisControl**)ppv=me,S_OK:E_OUTOFMEMORY; } return E_NOINTERFACE; } Debug through the code and you can see whats wrong in your modules. In this example the external interface refcount goes to zero when you call Release(). Sorry for the vanished tabs.

            A Offline
            A Offline
            AmitGG
            wrote on last edited by
            #5

            hi, Thanks Again. Your mail is helpful but I am very new to COM so find it a bit difficult to understand. You have written some server side code also. Here I want to know "Do we need to override the Addref() and Release() functions of IUnknown interfaces or there is no need to do it" Actually I have just got the DLL by building the C# code. I have not written the coding of Addref, QueryInterface and Release functions. Is that wrong ? I have posted an other message on the board which contains both codes (client side and server side). Can you please see that message and help me in sorting the problem out. I logged that message because for the problem of the present message I cannot provide server side code. Please see that message also and let me know your comments. Your mail is very very helpful to me and it may take me out of the misery I am going through for so long. I can just say Thank You Very Very Much, dear. Best Regards, -- modified at 6:39 Tuesday 28th February, 2006

            M 1 Reply Last reply
            0
            • A AmitGG

              hi, Thanks Again. Your mail is helpful but I am very new to COM so find it a bit difficult to understand. You have written some server side code also. Here I want to know "Do we need to override the Addref() and Release() functions of IUnknown interfaces or there is no need to do it" Actually I have just got the DLL by building the C# code. I have not written the coding of Addref, QueryInterface and Release functions. Is that wrong ? I have posted an other message on the board which contains both codes (client side and server side). Can you please see that message and help me in sorting the problem out. I logged that message because for the problem of the present message I cannot provide server side code. Please see that message also and let me know your comments. Your mail is very very helpful to me and it may take me out of the misery I am going through for so long. I can just say Thank You Very Very Much, dear. Best Regards, -- modified at 6:39 Tuesday 28th February, 2006

              M Offline
              M Offline
              mbue
              wrote on last edited by
              #6

              This was only a basically introduction how COM works. If you use abstract classes (your class is derived from) its not necessary to implement the basic functions again (from IUnknown). If you use C# you should never do that except you need it anyway. Remember the example is reduced to the native and also don't work outside inproc environments! Sorry it's only to understand the mechanism.

              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