Jacob Weitzman
Jacob Weitzman

Reputation: 3

Passing COM interface pointers to functions

I'm hoping someone can help with this question. I'm also hoping that this question has a simple answer. I feel like I'm missing something very obvious, but I'm new to C++ and have been unable to get past this issue.

I want to pass an IUpdateCollection to a function, put IUpdates into the collection, and then be able to access the collection outside of the function. In the code below, everything compiles/runs, but the count of items in the IUpdateCollection is 5 while inside the Searcher function, but when I later try to count the items in the IUpdateCollection from outside the function, the count is 0.

What am I missing here?

Thanks!

class W
{
public:
    // constructor
    W()
    {       
        //create the COM object to return the IUpdateSession interface pointer
        hr = CoCreateInstance( )
    }

    int Searcher(IUpdateCollection* pUpdateCollection)
    {                           

        //put the updates into our pUpdateCollection
        hr = pSearchResult->get_Updates(&pUpdateCollection);
        if(FAILED(hr) || pUpdateCollection == NULL)
        { cout << "Failed to put updates in the collection"; return -103; };

        long lUpdatesCount = NULL;
        hr = pUpdateCollection->get_Count(&lUpdatesCount);
        if(FAILED(hr) || pSearchResult == NULL)
        { cout << "Failed to get count of udpates in collection"; return -104; };

        cout << lUpdatesCount << endl;  //console outputs the actual count here, which at the moment is 5

        pUpdateSearcher->Release();     
        return 0;
    }
private:
    HRESULT hr;
    IUpdateSession* pUpdateSession; 
};

int main(int argc, char* argv[])
{
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    HRESULT hr;


    W myW;
    //pass the pUpdateCollection to the W.Searcher function
    myW.Searcher(pUpdateCollection);

    //get count of updates in collection
    long lUpdatesCount = NULL;
    pUpdateCollection->get_Count(&lUpdatesCount);

    cout << lUpdatesCount << endl;  //console outputs 0 here instead of the same count that it outputted in W.Searcher().  WHY?
    CoUninit();

    system("pause");
    return 0;
}

Upvotes: 0

Views: 1220

Answers (2)

Remus Rusanu
Remus Rusanu

Reputation: 294237

Use smart pointers like _com_ptr_t and _bstr_t. USing the raw pointers and directly operating BSTRs is nothing but pain.

#import-ing the COM DLL will create the typed smart pointers for you, including easy to use CreateInstance methods. Smart pointer also eliminate the need to explicitly check for HR after each call, they raise exceptions.

As to your question: it depends on the implementation/specification/documentation of your COM object. Perhaps releasing the IUpdateSearcher clears up the count, but is just speculation on my part. The relevant code would be the COM server, not the client.

didn't notice this is WUA, documented behavior

ISearchResult::Updates assigns the IUpdateCollection. Therefore you are passing in a value of the pointer, change it in the function scope, then expect the change to apply outside the scope. The very same thing you're doing, but using int:

void f(int a)
{
  a=5;
}

void main()
{
  int a = 7;
  f(a);
  printf("%d", a); -- of course is 7, not 5
}

You would solve the 'problem' for int by passing by ref or a pointer. Same applies to your COM pointer. And using _com_ptr_t would have clearly showed the issue :)

Upvotes: 1

Frank Boyne
Frank Boyne

Reputation: 4570

The Updates property returns an IUpdateCollection pointer which overwrites the contents of the pUpdateCollection parameter to your Searcher() method. The count you are inspecting inside Searcher is the count of that collection.

But you passed pUpdateCollection by value so when you exit Searcher the IUpdateCollection retrieved by get_Updates() is discarded.

To see this, place a breakpoint on your get_Updates() call and watch the value of pUpdateCollection change as you step over the get_Updates call. Then step out of Searcher and note that the value in main's pUpdateCollection has not changed.

Upvotes: 1

Related Questions