Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / October 2004

Tip: Looking for answers? Try searching our database.

Interop question:  .NET COM object created in C++ doesn't seem to get destroyed

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Robert Rossney - 30 Sep 2004 21:37 GMT
I have built a .NET COM object that's being instantiated by a (non-.NET) C++
application, using the following code:

  CoInitialize(NULL);
  IMyInterface *pCOMObject = NULL;
  HRESULT hr = CoCreateInstance(CLSID_MyDotNetClass,
     NULL,
     CLSCTX_INPROC_SERVER,
     IID_IMyInterface,
     reinterpret_cast<void**> (&pCOMObject));

  if (SUCCEEDED(hr)) {
     pCOMObject->Method(params);
     pCOMObject->Release();
     pCOMObject=NULL;
   }
   CoUninitialize();

The object gets created, the method gets called, the parameters get
passed...from that perspective, everything's working.

But the object doesn't seem to get destroyed when I release it.  The
object's destructor never gets called, and the DLL containing the object's
code remains locked until the C++ application terminates.  This seems wrong
to me -- especially since the above code is itself in a dynamically-loaded
function, and I can happily rebuild *its* DLL while the calling application
is running.

Is there something obvious I'm doing wrong here?

Thanks in advance,

Robert Rossney
rbr@well.com
David Browne - 01 Oct 2004 00:25 GMT
>I have built a .NET COM object that's being instantiated by a (non-.NET)
>C++
[quoted text clipped - 28 lines]
>
> Is there something obvious I'm doing wrong here?

No. All is well.

.NET objects don't have destructors.  If you use destructor syntax, you
actually create a finalizer.  The difference between a finalizer and a
descructor is that a destructor is called deterministically when the object
goes out of scope or is delete'd.  A finalizer is called later, after the
Garbage Collector runs and discovers that the object is no loger reachable
from any application root.  Your code will leave the .NET object alive on
the managed heap, but unreachable.  Its finalizer will run after garbage
collection.

If you need deterministic cleanup of a .NET object, implement IDisposable
and call IDisposable.Dispose from the client code.

As for the .DLL, when you call CoCreateObject to create the COM-Callable
wrapper for the .NET object, the CLR is fired up in your process and the
target assembly is loaded into the default AppDomain.  The CLR, the default
App Domain and your assembly will remain loaded for the duration of your
process.

David
Robert Rossney - 01 Oct 2004 17:16 GMT
: No. All is well.
:
[quoted text clipped - 9 lines]
: If you need deterministic cleanup of a .NET object, implement IDisposable
: and call IDisposable.Dispose from the client code.

You know, I actually already knew all this.  But I knew it on paper.  Now I
know it for real.

Also:  I see now from various documents I'm reading about managing the
lifetime of COM objects that the delete operator and COM objects don't mix,
and that setting the pointer to NULL was in fact the right thing to do after
calling Release() on it.  Deleting the object fired the destructor, but it
caused very bad things to happen.

: As for the .DLL, when you call CoCreateObject to create the COM-Callable
: wrapper for the .NET object, the CLR is fired up in your process and the
: target assembly is loaded into the default AppDomain.  The CLR, the default
: App Domain and your assembly will remain loaded for the duration of your
: process.

That makes sense.  It's annoying, because I can presently move a new build
of the C++ DLL into production without forcing all users to log off first,
and I won't once the DLL starts calling .NET objects, but it makes sense.
On the other hand, that also means that the CLR and the assembly aren't
being freshly loaded every time my object gets created, so really it's
better this way.

I went down this whole road because I wanted to make sure that my object was
getting destroyed, and when I implemented a destructor I found that it
wasn't.  I think that maybe I'll just trust COM to do its job and worry
about other things.

Thanks for your help.

Robert Rossney
rbr@well.com
Robert Rossney - 01 Oct 2004 05:33 GMT
:       pCOMObject=NULL;

Er, that should be

       delete pCOMObject;

Forgot what language I was programming in for a minute there.  Sorry about
that.

Robert Rossney
rbr@well.com

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.