Paresh Suthar's Radio Weblog : And that's all I have to say about that - Forrest Gump
Updated: 1/21/2005; 10:17:26 AM.

 








Subscribe to "Paresh Suthar's Radio Weblog" in Radio UserLand.

Click to see the XML version of this web page.

 
 

Wednesday, December 11, 2002

After running into some nasty errors while developing a C# project, I found that I was too aggressive in calling System.Runtime.InteropServices.Marshal.ReleaseComObject().  The specific problem is that after casting an interop interface IFoo to interop interface IBar, the Runtime Callable Wrapper (RCW) reference count is not incremented.  This means that the following code is wrong:
SomeClass.Interop.IFoo foo = (SomeClass.Interop.IFoo)new SomeClass.Interop.FooClass();
SomeClass.Interop.IBar bar = (SomeClass.Interop.IBar)foo;

// This call decrements RCW count to 0!
System.Runtime.InteropServices.Marshal.ReleaseComObject(foo);

// Nothing to release here!
System.Runtime.InteropServices.Marshal.ReleaseComObject(bar)

The solution for the scenario above is to only call ReleaseComObject once. But what do you do in the case where you pass an interop interface to another method/class while holding a reference to the original interop interface?

public class Test1 : IDispose
{
   private SomeClass.Interop.IFoo m_pIFoo;

   public void Test1()
   {
       m_pIFoo = (SomeClass.Interop.IFoo)new SomeClass.Interop.FooClass();
   }

   public SomeClass.Interop.IBar IBar
   {
      get
      {
       return (SomeClass.Interop.IBar)m_pIFoo;
      }
   }

   public void Dispose()
   {
      if (m_pIFoo != null)
         System.Runtime.InteropServices.Marshal.ReleaseComObject(m_pIFoo);
   }
}

public class Test2 : IDispose
{
   private SomeClass.Interop.IBar m_pIBar;

   public void Test2()
   {
       Test1 test1 = new Test1();
       m_pIBar = test1.IBar;

       // ; The following line of code decrements the RCW count to 0, making
       // ; m_pIBar invalid!
       test1.Dispose();
   }

   public void Dispose()
   {
      if (m_pIBar != null)
         System.Runtime.InteropServices.Marshal.ReleaseComObject(m_pIBar);
   }
}

I don't know how to solve the problem above yet, but will post any solutions I come across.


9:39:52 AM    comment []

© Copyright 2005 Paresh Suthar.



Click here to visit the Radio UserLand website.
 


December 2002
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Nov   Jan