Question about [in, out] parameters
-
I have been trying to write a Method on my COM interface that takes an [in, out] parameter. I expected that this would act like a I was passing in a reference. In the idl file the function is: [id(1), helpstring("method Select")] HRESULT Select([in, out] System** System); In the appropiate hear file the function is defined as: STDMETHOD(Select)(System** System); I use the function as below: //In some cases the pSystem object is created other times it will be null ISystemPtr pSystem(CLSID_System); //or ISystemPtr pSystem = NULL; //The Select Method will display a dialog with a set of options, if the object being passed in is //NOT NULL the dialog should have the correct / relavent options selected. If it is NULL the //pSystem object will be created with the selected options and passed back to the client. TheObjectWithTheMethod->Select(&pSystem); The problem is that when an valid (not NULL) pointer is passed into the function the & operator actually releases the pointer to the pSystem and returns a NULL interface pointer. So inside the implimentation of the Select function we always get a NULL pointer. Does anubody have any ideas? Cheers Andy
-
I have been trying to write a Method on my COM interface that takes an [in, out] parameter. I expected that this would act like a I was passing in a reference. In the idl file the function is: [id(1), helpstring("method Select")] HRESULT Select([in, out] System** System); In the appropiate hear file the function is defined as: STDMETHOD(Select)(System** System); I use the function as below: //In some cases the pSystem object is created other times it will be null ISystemPtr pSystem(CLSID_System); //or ISystemPtr pSystem = NULL; //The Select Method will display a dialog with a set of options, if the object being passed in is //NOT NULL the dialog should have the correct / relavent options selected. If it is NULL the //pSystem object will be created with the selected options and passed back to the client. TheObjectWithTheMethod->Select(&pSystem); The problem is that when an valid (not NULL) pointer is passed into the function the & operator actually releases the pointer to the pSystem and returns a NULL interface pointer. So inside the implimentation of the Select function we always get a NULL pointer. Does anubody have any ideas? Cheers Andy
Use a ** when you want to pass a pointer to an object and you might want it to return a pointer to a different object. Consider:
HRESULT Select( System** pSystem )
{
if ( pSystem != NULL )
(*pSystem)->Release();*pSystem = new System();
}pSystem = new System();
HRESULT hr = Select( &pSystem );// pSystem now points to a different System object
If you don't want to change the value of the pointer you pass in, but instead change the value of the object, use a single *. I think that you actually do want to pass the pointer by reference, but your
ISystemPtr
smart pointer class has an override ofoperator &
which I assume is releasing the held pointer. Without seeing this class, or what the typedef is, it's difficult to help. The documentation for_com_ptr_t
, the environment's own smart pointer, suggests that operator&[^] releases the pointer then NULLs it. IIRC, using#import
generates smart pointer typedefs of_com_ptr_t
. If this is what you're using, I think all you can do isDetach
the pointer, call Select, thenAttach
the resulting pointer to the smart pointer object. ATL'sCComPtr
allows direct access to the raw pointer through the publicp
member. Itsoperator&
ASSERTs if the contained pointer is not NULL. Stability. What an interesting concept. -- Chris Maunder -
Use a ** when you want to pass a pointer to an object and you might want it to return a pointer to a different object. Consider:
HRESULT Select( System** pSystem )
{
if ( pSystem != NULL )
(*pSystem)->Release();*pSystem = new System();
}pSystem = new System();
HRESULT hr = Select( &pSystem );// pSystem now points to a different System object
If you don't want to change the value of the pointer you pass in, but instead change the value of the object, use a single *. I think that you actually do want to pass the pointer by reference, but your
ISystemPtr
smart pointer class has an override ofoperator &
which I assume is releasing the held pointer. Without seeing this class, or what the typedef is, it's difficult to help. The documentation for_com_ptr_t
, the environment's own smart pointer, suggests that operator&[^] releases the pointer then NULLs it. IIRC, using#import
generates smart pointer typedefs of_com_ptr_t
. If this is what you're using, I think all you can do isDetach
the pointer, call Select, thenAttach
the resulting pointer to the smart pointer object. ATL'sCComPtr
allows direct access to the raw pointer through the publicp
member. Itsoperator&
ASSERTs if the contained pointer is not NULL. Stability. What an interesting concept. -- Chris MaunderMike Dimmick wrote: *pSystem = new System(); *ahem* You forgot an
AddRef()
:) -- My name in Katakana is ヨルゲン. My name in German is Jörgen. I blog too now[^]