471,318 Members | 3,236 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,318 software developers and data experts.

COM Events passing Object as parameter (problem)

I have a ATL COM object that is loaded through Interop in a C# application.
The COM object fires an event and one of the parameters is another object
created inside the object. This object has a property on it that is also
another object.
private void pIObj_EventProc(MObj.MainObj pObj)
{
MObj.Obj mainobj = pObj.Obj;
// IF I DON'T DO THE NEXT LINE, THE APPLICATION HANGS AT SOME LATER TIME
// THE UI DOESN'T EVEN UPDATE.
System.Runtime.InteropServices.Marshal.ReleaseComO bject(mainobj);
}

Property in ATL Object that returns another object...
HRESULT CMainObj::get_Obj(IObj** pVal)
{
IObj* pIObj= NULL;
CComObject<CObj>* pObj;
if (S_OK == CComObject<CObj>::CreateInstance(&pObj)
&& S_OK == pObj->QueryInterface(IID_IObj, (void**)&pIObj))
{
*pVal = pIObj;
return S_OK;
}
}

I don't fully understand interop but I'm thinking this could be the source
of my problem. Is there a way to make this reliable from the COM object
perspective? I'd rather not require the user to do the ReleaseComObject in
order to prevent their application from hanging at some random time.
Everything works correctly if the host is C++ or JScript or other such
languages.

Any help would be appreciated.
Dec 9 '05 #1
4 3777
"Jayme Pechan" <ja**********@whitefeld.com> wrote in message
news:O1*************@TK2MSFTNGP15.phx.gbl...
I have a ATL COM object that is loaded through Interop in a C# application.
The COM object fires an event and one of the parameters is another object
created inside the object. This object has a property on it that is also
another object.
private void pIObj_EventProc(MObj.MainObj pObj)
{
MObj.Obj mainobj = pObj.Obj;
// IF I DON'T DO THE NEXT LINE, THE APPLICATION HANGS AT SOME LATER
TIME
// THE UI DOESN'T EVEN UPDATE.
System.Runtime.InteropServices.Marshal.ReleaseComO bject(mainobj);
}


Here's my understanding of how com interop works. Dot net will create a
wrapper class around your com object. It will increment the ref count to 1
and keep it at 1 no matter how many references to the wrapper you create. It
will decrement it to zero if you call ReleaseComObject. You can still have
references to the wrapper after this but they will not function. If you do
the opposite and release all your references without calling
ReleaseComObject then the reference count will stay at 1 until the garbage
collector gets it. I'd say this is your problem in that the garbage
collector is causing your objects to be released in a different order to
what you'd normally expect. My guess would be that if you look in the code
for Release of your object you'll find the problem, maybe it references
another object there that has already been destroyed?

Michael
Dec 9 '05 #2
Michael,

Thanks for the response. Its an interesting idea. In my test program,
there is nothing at all in the objects except the one property for returning
the other object. It still happens even if I store a reference to the
parameter object in a local variable in C# (should maintain the reference
count). In the ATL object, if I do not release the object after firing the
event, it works fine except that the MainObj never gets released in C# or
any other language.

Jayme
Dec 9 '05 #3

"Jayme Pechan" <ja**********@whitefeld.com> wrote in message
news:O1*************@TK2MSFTNGP15.phx.gbl...
I have a ATL COM object that is loaded through Interop in a C# application.
The COM object fires an event and one of the parameters is another object
created inside the object. This object has a property on it that is also
another object.
private void pIObj_EventProc(MObj.MainObj pObj)
{
MObj.Obj mainobj = pObj.Obj;
// IF I DON'T DO THE NEXT LINE, THE APPLICATION HANGS AT SOME LATER
TIME
// THE UI DOESN'T EVEN UPDATE.
System.Runtime.InteropServices.Marshal.ReleaseComO bject(mainobj);
}

Property in ATL Object that returns another object...
HRESULT CMainObj::get_Obj(IObj** pVal)
{
IObj* pIObj= NULL;
CComObject<CObj>* pObj;
if (S_OK == CComObject<CObj>::CreateInstance(&pObj)
&& S_OK == pObj->QueryInterface(IID_IObj, (void**)&pIObj))
{
*pVal = pIObj;
return S_OK;
}
}

I don't fully understand interop but I'm thinking this could be the source
of my problem. Is there a way to make this reliable from the COM object
perspective? I'd rather not require the user to do the ReleaseComObject
in order to prevent their application from hanging at some random time.
Everything works correctly if the host is C++ or JScript or other such
languages.

Any help would be appreciated.


What kind of ATL object s this, a simple object or an AX control or...?
What kind of C# aplication is this? Where did you create the instance of the
COM object, which thread what's his threading attribute (STA/MTA)?
What exactly are you doing with the mainobj in your pIObj_EventProc?

Willy.

Dec 9 '05 #4
As it turns out, one of the objects being passed into the event handler was
created on a thread declared as Apartment model and I hadn't implemented the
required message loop. Since in this case I could not implement a message
loop because of another message processing loop I was doing, I simply
declared the thread as free threaded and it works fine. I have to worry
about accessability of the members on these objects but since they are all
read only members, that was not difficult.

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:ep*************@tk2msftngp13.phx.gbl...

"Jayme Pechan" <ja**********@whitefeld.com> wrote in message
news:O1*************@TK2MSFTNGP15.phx.gbl...
I have a ATL COM object that is loaded through Interop in a C#
application. The COM object fires an event and one of the parameters is
another object created inside the object. This object has a property on
it that is also another object.
private void pIObj_EventProc(MObj.MainObj pObj)
{
MObj.Obj mainobj = pObj.Obj;
// IF I DON'T DO THE NEXT LINE, THE APPLICATION HANGS AT SOME LATER
TIME
// THE UI DOESN'T EVEN UPDATE.
System.Runtime.InteropServices.Marshal.ReleaseComO bject(mainobj);
}

Property in ATL Object that returns another object...
HRESULT CMainObj::get_Obj(IObj** pVal)
{
IObj* pIObj= NULL;
CComObject<CObj>* pObj;
if (S_OK == CComObject<CObj>::CreateInstance(&pObj)
&& S_OK == pObj->QueryInterface(IID_IObj, (void**)&pIObj))
{
*pVal = pIObj;
return S_OK;
}
}

I don't fully understand interop but I'm thinking this could be the
source of my problem. Is there a way to make this reliable from the COM
object perspective? I'd rather not require the user to do the
ReleaseComObject in order to prevent their application from hanging at
some random time. Everything works correctly if the host is C++ or
JScript or other such languages.

Any help would be appreciated.


What kind of ATL object s this, a simple object or an AX control or...?
What kind of C# aplication is this? Where did you create the instance of
the COM object, which thread what's his threading attribute (STA/MTA)?
What exactly are you doing with the mainobj in your pIObj_EventProc?

Willy.

Jan 13 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Jon Davis | last post: by
6 posts views Thread by Catherine Jones | last post: by
5 posts views Thread by blue | last post: by
6 posts views Thread by MSDNAndi | last post: by
4 posts views Thread by Dave A | last post: by
16 posts views Thread by anonymous.user0 | last post: by
5 posts views Thread by Daniel | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.