-1

The code to be referred to is:

Dim oXL As Microsoft.Office.Interop.Excel.Application
Dim oWBS As Workbooks
Dim oWB As Workbook
Dim oSheet As Worksheet
    
oXL = CreateObject("Excel.Application")
oWBS = oXL.Workbooks
oWB = oWBS.Add

Summary of the detailed explanation presented below: In the above code oXL, oWBS, oWB and oSheet are all storing references. By definition, a reference must point to a memory location. What I want to understand is whether they point to the same or different memory locations?

My thoughts: I have highlighted my questions in bold My guess is that these memory locations representing the various references are all different from one another. I imagine the representations as follows. Say oXL (representing the Excel Application) points to a location ‘A’ inside the memory. The Workbooks property returns an instance of the Workbooks collection. oWBS stores the reference returned by oXL.Workbooks and points to a new location, say B which is tagged to Location A. I mention “tagging” because oWBS is created against oXL. The reference oWBS can access the ADD method. When the ADD method is executed it adds a workbook or in more technical terms returns a WORKBOOK object (which is also a reference). oWB stores this reference and by definition must be pointing at some memory location, say C which gets tagged to B.

My Question: Are A, B, C are all different memory locations? Although I may be wrong, I can still imagine A and B to be separate memory locations. But what about B and C? The memory location representing the Workbooks collection (B) and the location which actually holds the workbook (with one sheet in it) that is C – should they be really different locations? If not, then are the two reference oWBS and oWB pointing to the same location – how to explain that??

Generalizing the above line of thought, does it mean that whenever we execute oXL.Workbooks.ADD to add a new workbook we are returned three references?

  1. a reference denoting the excel application
  2. a reference denoting the instance of oXL.Workbooks collection
  3. a reference denoting the single workbook that gets added

Now let’s add a worksheet to a workbook, using _Workbook.Worksheets.ADD. Extending the above reasoning would we be again getting unique references (pointing to new memory locations) for _Workbook.Worksheets and Worksheets.ADD??

Also, I want to state that this is more of an academic curiosity.

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
Sougata
  • 319
  • 1
  • 10
  • 2
    Yes, they are all distinct references. No, do not use Marshal.ReleaseComObject(). – Hans Passant Jan 03 '22 at 12:46
  • @HansPassant many thanks for answering. But could you pls explain why you mentioned to not use Marshal.ReleaseComObject()? – Sougata Jan 03 '22 at 13:07
  • 1
    They all point to the same Virtual Function Table. The first 4 functions are IUnknown (AddRef, Release (subtract 1 from ref), QueryInterface which usually returns the same VTable. After IUknown functions come the object specific functions. Usually, but they don't have to be, other objects are just tacked on in the same VTable. See https://learn.microsoft.com/en-us/windows/win32/api/unknwn/nn-unknwn-iunknown. – KL-1 Jan 03 '22 at 20:45
  • This page used to be on MS's web site. It lists what CreateObject et al does. https://stackoverflow.com/questions/61178839/what-is-the-difference-between-new-object-comobject-in-powershell-and-createobj . In the Vtable is the address of the function. – KL-1 Jan 03 '22 at 20:45
  • 1
    An actual COM object is 4 x 32 bytes. 2 x 32 bit numbers are unused, 1 holds the reference count and the other is the address of the VTable. – KL-1 Jan 04 '22 at 02:31
  • `why you mentioned to not use Marshal.ReleaseComObject` - https://stackoverflow.com/a/38170605/11683, https://stackoverflow.com/a/25135685/11683. – GSerg Jan 04 '22 at 20:51
  • Sougata, I understand your comments on the answer that you have edited the question so that the answer is not valid anymore. That is considered a "moving target" question and not appreciated. If you have a new question please ask it as a separate dedicated question. Feel free to improve this question by [edit]ing, but please only to improve the question in its original scope. – Yunnosch Jan 04 '22 at 20:52
  • 1
    COM isn't about objects. It is about interfaces allowing objects to use each other. A COM object is a table of function calls. The programming language uses COM to allow its concept of objects to communicate with other objects written in any language, including non COM and non object languages (you have to do a lot of API calls). Perhaps your question is actually about what Excel does. COM loads a library and returns IUnknown. Excel adds ref then queries IUnknown for the VTable it wants. – KL-1 Jan 04 '22 at 21:55
  • @Yunnosch I agree. Shall keep in mind. – Sougata Jan 05 '22 at 04:40

1 Answers1

2

By definition, a reference must point to a memory location. What I want to understand is whether they point to the same or different memory locations?

In the COM world object reference doesn't point to a memory location, especially in a managed applications written in VB.NET. In .Net you deal with an RCW object which routes your calls to the COM object. Read more about that in the Runtime Callable Wrapper article in MSDN. It states the following:

The runtime creates exactly one RCW for each COM object, regardless of the number of references that exist on that object. The runtime maintains a single RCW per process for each object. If you create an RCW in one application domain or apartment, and then pass a reference to another application domain or apartment, a proxy to the first object will be used. Note that this proxy is a new managed object and not the same as the initial RCW; this means the two managed objects are not equal but do represent the same COM object.

In the COM world when you call a property or method, for example, the oXL.Workbooks property returns an instance of the Workbooks class and increases the reference counter of the corresponding COM object. Say, if you call the property twice in a raw you will get a new object instance in .NET and the refence counter will be increased twice. In that case you need to call the Marshal.ReleaseComObject for each object returned to decrease the refence counter.

Finally, you may find the Why doesn’t Excel quit? article helpful.


Also, in this context is there a way to display the reference count against a COM object?

The Marshal.ReleaseComObject method returns a new value of the reference count of the RCW associated with a COM object.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • hi..pls note that I have unmarked the answer because I had edited my question. I am not sure but I have a feeling that if a question is marked answered, most probably it wont be noticed by people. But I want to inform you that your post was quite helpful and it was based on your comments that I was able to ask a more specific question. So thank you! – Sougata Jan 04 '22 at 14:22
  • 1
    I'd suggest posting new question separately instead of re-placing question with an answer posted. – Eugene Astafiev Jan 04 '22 at 20:44
  • yes. I agree. The thing is for some reason this question got downvoted. When I tried asking a new question, the website prompted that if I do so and that question also gets downvoted I would be at the risk of being debarred from asking questions. Rather, I should try and improve my existing questions. Hence although I modified the question (which has now been reverted back), I shall keep your suggestion in mind. I request you to understand. – Sougata Jan 05 '22 at 04:42