locked
QueryInterface and E_POINTER return value. RRS feed

  • Question

  • Here is how this function looks:

    HRESULT QueryInterface ( [in] REFIID riid , [out] void * * ppvObject ) ;

    In the description of ppvObject parameter it says that it should contain the address of a pointer variable that receives the interface pointer requested in the riid parameter.

    Then it says if ppvObject is NULL, this method returns E_POINTER.

    Does it mean that before ppvObject is passed to QueryInterface it can not be initialized with NULL but instead it's value must be allocated with some memory function therefore contain non NULL value? That puzzles me since I always initialized ppvObject to NULL before passing it to my server's QueryInterface and wasn't checking whether it's NULL or not in QueryInterface itself returning E_POINTER in case it was NULL.

    Any guidance, explanation or confirmation on this matter would be appreciated. Thanks.

    Friday, November 26, 2010 12:35 AM

Answers

  • Victor Stout wrote:

    HRESULT QueryInterface ( [in] REFIID riid , [out] void * * ppvObject )  ;

    In the description of ppvObject parameter it says that it should  contain the address of a pointer variable that receives the
    interface pointer requested in the riid parameter.

    Then it says if ppvObject is NULL, this method returns E_POINTER.

    Why is this surprising? NULL can't possibly be an address of a pointer  variable.

    Does it mean that before ppvObject is passed to QueryInterface it can  not be initialized with NULL

    Of course. It must be initialized with an address of a pointer variable.  *ppvObject, on the other hand, may be NULL.

    but instead it's value must be
    allocated with some memory function therefore contain non NULL value?

    One doesn't need any "memory function" to obtain a non-NULL pointer.  Just take the address of a variable (could be an automatic variable on  the stack), as the documentation suggests.

    That puzzles me since I always initialized ppvObject to
    NULL before passing it to my server's QueryInterface

    Did not.


    Igor Tandetnik

    • Marked as answer by Victor Stout Friday, November 26, 2010 5:01 AM
    Friday, November 26, 2010 3:35 AM
  • Hello Victor,

     

    1. I believe that most likely you have coded as follows :

      IInterfaceB* pIInterfaceB = NULL;

      pIInterfaceA -> QueryInterface(IID_IInterfaceB, (void**)&pIInterfaceB);

     

    2. The above is perfectly fine.

    2.1 It is equivalent to the following code :

      IInterfaceB*  pIInterfaceB = NULL;
      IInterfaceB** ppIInterfaceB = &pIInterfaceB;

      pIInterfaceA -> QueryInterface(IID_IInterfaceB, (void**)ppIInterfaceB);


    2.2 Hence you did not pass a NULL pointer to QueryInterface().

    2.3 You had passed the address of pIInterfaceB to QueryInterface().

    2.4 It is pIInterfaceB that is set to NULL. Not ppIInterfaceB.

    - Bio.

     

    • Marked as answer by Victor Stout Friday, November 26, 2010 5:01 AM
    Friday, November 26, 2010 4:31 AM

All replies

  • Victor Stout wrote:

    HRESULT QueryInterface ( [in] REFIID riid , [out] void * * ppvObject )  ;

    In the description of ppvObject parameter it says that it should  contain the address of a pointer variable that receives the
    interface pointer requested in the riid parameter.

    Then it says if ppvObject is NULL, this method returns E_POINTER.

    Why is this surprising? NULL can't possibly be an address of a pointer  variable.

    Does it mean that before ppvObject is passed to QueryInterface it can  not be initialized with NULL

    Of course. It must be initialized with an address of a pointer variable.  *ppvObject, on the other hand, may be NULL.

    but instead it's value must be
    allocated with some memory function therefore contain non NULL value?

    One doesn't need any "memory function" to obtain a non-NULL pointer.  Just take the address of a variable (could be an automatic variable on  the stack), as the documentation suggests.

    That puzzles me since I always initialized ppvObject to
    NULL before passing it to my server's QueryInterface

    Did not.


    Igor Tandetnik

    • Marked as answer by Victor Stout Friday, November 26, 2010 5:01 AM
    Friday, November 26, 2010 3:35 AM
  • Hello Victor,

     

    1. I believe that most likely you have coded as follows :

      IInterfaceB* pIInterfaceB = NULL;

      pIInterfaceA -> QueryInterface(IID_IInterfaceB, (void**)&pIInterfaceB);

     

    2. The above is perfectly fine.

    2.1 It is equivalent to the following code :

      IInterfaceB*  pIInterfaceB = NULL;
      IInterfaceB** ppIInterfaceB = &pIInterfaceB;

      pIInterfaceA -> QueryInterface(IID_IInterfaceB, (void**)ppIInterfaceB);


    2.2 Hence you did not pass a NULL pointer to QueryInterface().

    2.3 You had passed the address of pIInterfaceB to QueryInterface().

    2.4 It is pIInterfaceB that is set to NULL. Not ppIInterfaceB.

    - Bio.

     

    • Marked as answer by Victor Stout Friday, November 26, 2010 5:01 AM
    Friday, November 26, 2010 4:31 AM
  • Igor Tandetnik, Lim Bio Liong, thank you very much.
    Friday, November 26, 2010 5:03 AM