COM interface disappears from ROT [modified]
-
I have two applications, both of which I have written. AppA was written in C++ using MFC. During startup it registers a CSingleDocTemplate and creates a document. The document provides a COM interface and registers itself in the ROT:
LPUNKNOWN punk = GetInterface(&IID_Welder); // doesn't AddRef
::RegisterActiveObject(punk, CLSID_Interface, ACTIVEOBJECT_WEAK, &m_dwRegister);AppA revokes the entry in the ROT when it is destroyed:
if (m_dwRegister)
::RevokeActiveObject(m_dwRegister, NULL);The destructor is only called when AppA terminates. AppB is written in C# and is a client of the interface provided by AppA:
private void Connect()
{
welderInterface = (Welder.Interface)Marshal.GetActiveObject("Welder.Interface");
Marshal.GetIUnknownForObject(welderInterface); // AddRef's it ...
}private void Disconnect()
{
if (welderInterface != null)
{
Marshal.ReleaseComObject(welderInterface);
welderInterface = null;
}
}(error handling omitted for clarity) That all works perfectly the first time AppB runs after AppA has started; AppB can call
Connect
andDisconnect
as often as it wants and use the interface between. However, if AppB terminates and runs again (AppA still running) the interface is no longer available -Marshal.GetActiveObject
throws an exception fromMK_E_UNAVAILABLE
. The only way to make the interface available again is to restart AppA - not an acceptable solution! Please can someone suggest how I might fix this?Phil
The opinions expressed in this post are not necessarily those of the author, especially if you find them impolite, inaccurate or inflammatory.
modified on Monday, August 2, 2010 7:16 AM
-
I have two applications, both of which I have written. AppA was written in C++ using MFC. During startup it registers a CSingleDocTemplate and creates a document. The document provides a COM interface and registers itself in the ROT:
LPUNKNOWN punk = GetInterface(&IID_Welder); // doesn't AddRef
::RegisterActiveObject(punk, CLSID_Interface, ACTIVEOBJECT_WEAK, &m_dwRegister);AppA revokes the entry in the ROT when it is destroyed:
if (m_dwRegister)
::RevokeActiveObject(m_dwRegister, NULL);The destructor is only called when AppA terminates. AppB is written in C# and is a client of the interface provided by AppA:
private void Connect()
{
welderInterface = (Welder.Interface)Marshal.GetActiveObject("Welder.Interface");
Marshal.GetIUnknownForObject(welderInterface); // AddRef's it ...
}private void Disconnect()
{
if (welderInterface != null)
{
Marshal.ReleaseComObject(welderInterface);
welderInterface = null;
}
}(error handling omitted for clarity) That all works perfectly the first time AppB runs after AppA has started; AppB can call
Connect
andDisconnect
as often as it wants and use the interface between. However, if AppB terminates and runs again (AppA still running) the interface is no longer available -Marshal.GetActiveObject
throws an exception fromMK_E_UNAVAILABLE
. The only way to make the interface available again is to restart AppA - not an acceptable solution! Please can someone suggest how I might fix this?Phil
The opinions expressed in this post are not necessarily those of the author, especially if you find them impolite, inaccurate or inflammatory.
modified on Monday, August 2, 2010 7:16 AM
My guess is that when you do this:
Phil J Pearson wrote:
Marshal.ReleaseComObject(welderInterface);
your object's reference count reaches zero and it gets destroyed. If this is your COM object, try initializing its reference counter to 1 (i guess it is zero now), or AddRef it after creation and Release when your AppA exits.
> The problem with computers is that they do what you tell them to do and not what you want them to do. < > "It doesn't work, fix it" does not qualify as a bug report. < > Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
-
My guess is that when you do this:
Phil J Pearson wrote:
Marshal.ReleaseComObject(welderInterface);
your object's reference count reaches zero and it gets destroyed. If this is your COM object, try initializing its reference counter to 1 (i guess it is zero now), or AddRef it after creation and Release when your AppA exits.
> The problem with computers is that they do what you tell them to do and not what you want them to do. < > "It doesn't work, fix it" does not qualify as a bug report. < > Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
No, that's not it. as I said: 1. The destructor is only called when AppA exits (checked in the debugger). 2. AppB can call Connect and Disconnect many times without problem. The problem only occurs when AppB exits. There's nothing special done with the interface on exit.
Phil
The opinions expressed in this post are not necessarily those of the author, especially if you find them impolite, inaccurate or inflammatory.
-
No, that's not it. as I said: 1. The destructor is only called when AppA exits (checked in the debugger). 2. AppB can call Connect and Disconnect many times without problem. The problem only occurs when AppB exits. There's nothing special done with the interface on exit.
Phil
The opinions expressed in this post are not necessarily those of the author, especially if you find them impolite, inaccurate or inflammatory.
How did you check that your interface isn't deleted when AppB exits? I mean,
Phil J Pearson wrote:
(checked in the debugger).
explain this, please.
> The problem with computers is that they do what you tell them to do and not what you want them to do. < > "It doesn't work, fix it" does not qualify as a bug report. < > Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
-
How did you check that your interface isn't deleted when AppB exits? I mean,
Phil J Pearson wrote:
(checked in the debugger).
explain this, please.
> The problem with computers is that they do what you tell them to do and not what you want them to do. < > "It doesn't work, fix it" does not qualify as a bug report. < > Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
Logging code and breakpoints in the doc destructor and in the doc
OnFinalRelease
. Only called when AppA exits - not AppB.Phil
The opinions expressed in this post are not necessarily those of the author, especially if you find them impolite, inaccurate or inflammatory.
-
My guess is that when you do this:
Phil J Pearson wrote:
Marshal.ReleaseComObject(welderInterface);
your object's reference count reaches zero and it gets destroyed. If this is your COM object, try initializing its reference counter to 1 (i guess it is zero now), or AddRef it after creation and Release when your AppA exits.
> The problem with computers is that they do what you tell them to do and not what you want them to do. < > "It doesn't work, fix it" does not qualify as a bug report. < > Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
Oops! Sorry! I take back my earlier rejection of your reply. It seems that the interface was being destroyed even though the document that implements it was not. I AddRef'd the interface in the doc constructor and Release'd it again in the destructor as you suggested and the problem is solved. Thank you!
Phil
The opinions expressed in this post are not necessarily those of the author, especially if you find them impolite, inaccurate or inflammatory.
-
Oops! Sorry! I take back my earlier rejection of your reply. It seems that the interface was being destroyed even though the document that implements it was not. I AddRef'd the interface in the doc constructor and Release'd it again in the destructor as you suggested and the problem is solved. Thank you!
Phil
The opinions expressed in this post are not necessarily those of the author, especially if you find them impolite, inaccurate or inflammatory.
It happens...great it works now. :thumbsup:
> The problem with computers is that they do what you tell them to do and not what you want them to do. < > "It doesn't work, fix it" does not qualify as a bug report. < > Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <