Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 613161
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T17:58:20+00:00 2026-05-13T17:58:20+00:00

I have rephrased this question. When .net objects are exposed to COM Clients through

  • 0

I have rephrased this question.

When .net objects are exposed to COM Clients through COM iterop, a CCW (COM Callable Wrapper) is created, this sits between the COM Client and the Managed .net object.

In the COM world, objects keep a count of the number of references that other objects have to it. Objects are deleted/freed/collected when that reference count goes to Zero. This means that COM Object termination is deterministic (we use Using/IDispose in .net for deterministic termination, object finalizers are non deterministic).

Each CCW is a COM object, and it is reference counted like any other COM object. When the CCW dies (reference count goes to Zero) the GC won’t be able to find the CLR object the CCW wrapped, and the CLR object is eligible for collection. Happy days, all is well with the world.

What I would like to do is catch when the CCW dies (i.e. when its reference count goes to zero), and somehow signal this to the CLR object (e.g. By calling a Dispose method on the managed object).

So, is it possible to know when the reference count of a COM Callable Wrapper for a CLR class goes to Zero?
and/or
Is it possible to provide my implementation of AddRef & ReleaseRef for CCWs in .net?

If not the alternative is to implement these DLLs in ATL (I don’t need any help with ATL, thanks). It wouldn’t be rocket science but I’m reluctant to do it as I’m the only developer in-house with any real world C++, or any ATL.

Background
I’m re-writing some old VB6 ActiveX DLLs in .net (C# to be exact, but this is more a .net / COM interop problem rather than a C# problem). Some of the old VB6 objects depend on reference counting to carry out actions when the object terminates (see explaination of reference counting above). These DLL’s don’t contain important business logic, they are utilities and helper functions that we provide to clients that integrate with us using VBScript.

What I’m not trying to do

  • Reference count .net objects instead
    of the using the Garbage Collector.
    I’m quite happy with the GC, my
    problem isn’t with the GC.
  • Use object finalizers. Finalizers are
    non deterministic, in this instance I
    need deterministic termination (like
    the Using/IDispose idiom in .net)
  • Implement IUnknown in unmanaged C++
    If I’ve to go the C++ route I’ll use
    ATL, thanks.
  • Solve this using Vb6, or re-using the
    VB6 objects. The entire point of
    this exercise is to remove our build
    dependence on Vb6.

Thanks
BW

The Accepted Answer
Folks a thousand thanks to Steve Steiner, who came up with the only (possibly workable) .net based answer, and Earwicker, who came up with a very simple ATL solution.

However the accepted answer goes to Bigtoe, who suggests wrapping the .net objects in VbScript objects (which I hadn’t considered to be honest), effectively providing a simple VbScript solution to a VbScript problem.

Thanks to all.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T17:58:21+00:00Added an answer on May 13, 2026 at 5:58 pm

    OK Folks, here’s another attempt at it. You can actually use “Windows Script Components” to wrap your .NET COM objects and get finalization that way. Here’s a full sample using a simple .NET Calculator which can Add values. I’m sure you’ll get the concept from there, this totally avoids the VB-Runtime, ATL issues and uses the Windows Scripting Host which is available on every major WIN32/WIN64 platform.

    I created a simple COM .NET Class called Calculator in a namespaces called DemoLib. Note this implements IDisposable where for demo purpose I put something up on the screen to show it has terminated. I’m sticking totally to vb here in .NET and script to keep things simple, but the .NET portion can be in C# etc. When you save this file you’ll need to register it with regsvr32, it will need to be saved as something like CalculatorLib.wsc.

    <ComClass(Calculator.ClassId, Calculator.InterfaceId, Calculator.EventsId)> _
    Public Class Calculator
        Implements IDisposable
    #Region "COM GUIDs"
        ' These  GUIDs provide the COM identity for this class 
        ' and its COM interfaces. If you change them, existing 
        ' clients will no longer be able to access the class.
        Public Const ClassId As String = "68b420b3-3aa2-404a-a2d5-fa7497ad0ebc"
        Public Const InterfaceId As String = "0da9ab1a-176f-49c4-9334-286a3ad54353"
        Public Const EventsId As String = "ce93112f-d45e-41ba-86a0-c7d5a915a2c9"
    #End Region
        ' A creatable COM class must have a Public Sub New() 
        ' with no parameters, otherwise, the class will not be 
        ' registered in the COM registry and cannot be created 
        ' via CreateObject.
        Public Sub New()
            MyBase.New()
        End Sub
        Public Function Add(ByVal x As Double, ByVal y As Double) As Double
            Return x + y
        End Function
        Private disposedValue As Boolean = False        ' To detect redundant calls
        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    MsgBox("Disposed called on .NET COM Calculator.")
                End If
            End If
            Me.disposedValue = True
        End Sub
    #Region " IDisposable Support "
        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
    #End Region
    End Class
    

    Next I create A Windows Script Component called Calculator.Lib which has a single method which returns back a VB-Script COM class which exposes the .NET Math Library. Here I pop up something on the screen during Construction and Destruction, note in the Destruction we call the Dispose method in the .NET library to free up resources there. Note the use of the Lib() function to return the .NET Com Calculator to the caller.

    <?xml version="1.0"?>
    <component>
    <?component error="true" debug="true"?>
    <registration
        description="Demo Math Library Script"
        progid="Calculator.Lib"
        version="1.00"
        classid="{0df54960-4639-496a-a5dd-a9abf1154772}"
    >
    </registration>
    <public>
      <method name="GetMathLibrary">
      </method>
    </public>
    <script language="VBScript">
    <![CDATA[
    Option Explicit
    '-----------------------------------------------------------------------------------------------------
    ' public Function to return back a logger.
    '-----------------------------------------------------------------------------------------------------
    function GetMathLibrary()
        Set GetMathLibrary = New MathLibrary
    end function
    Class MathLibrary
        private dotNetMatFunctionLib
      private sub class_initialize()
        MsgBox "Created."
        Set dotNetMatFunctionLib = CreateObject("DemoLib.Calculator")
      end sub
      private sub class_terminate()
            dotNetMatFunctionLib.Dispose()
            Set dotNetMatFunctionLib = nothing
        MsgBox "Terminated."
      end sub
      public function Lib()
        Set Lib = dotNetMatFunctionLib
      End function
    end class
    ]]>
    </script>
    </component>
    

    Finally to tie it all together here’s s sample VB script where you get dialogues showing creation, the calculation, dispose being called in the .NET library and finally Terminate in the COM component exposing the .NET Component.

    dim comWrapper
    dim vbsCalculator
    set comWrapper = CreateObject("Calculator.Lib")
    set vbsCalculator = comWrapper.GetMathLibrary()
    msgbox "10 + 10 = " & vbsCalculator.lib.Add(10, 10)
    msgbox "20 + 20 = " & vbsCalculator.lib.Add(20, 20)
    set vbsCalculator = nothing
    MsgBox("Dispose & Terminate should have been called before here.")
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.