2012-07-02 2 views
0

Я новичок в COM и smartpointers, я пытаюсь преобразовать проект из raw pointers в CComPtr, чтобы избежать проблем с управлением памятью. Я ищу несколько советов о том, как правильно использовать CComPointers, когда речь идет о функциях и области в целом. Образец моего кода.Как правильно использовать CComPtr в вызовах функций?

int DisplayDeviceInformation(IEnumMoniker * pEnum, IMoniker * pMoniker) 
{ 
    CComPtr<IPropertyBag> pPropBag = NULL; 

    while (pEnum->Next(1, &pMoniker, NULL) == S_OK) 
    { 

     HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag)); 
     if (FAILED(hr)) 
     { 

     } 

     VARIANT var; 
     VariantInit(&var); 

     // Get description or friendly name. 
     hr = pPropBag->Read(L"Description", &var, 0); 
     if (FAILED(hr)) 
     { 
      hr = pPropBag->Read(L"FriendlyName", &var, 0); 
     } 
     if (SUCCEEDED(hr)) 
     { 
      printf("%S\n", var.bstrVal); 
      VariantClear(&var); 
     } 

     hr = pPropBag->Write(L"FriendlyName", &var); 

     // WaveInID applies only to audio capture devices. 
     hr = pPropBag->Read(L"WaveInID", &var, 0); 
     if (SUCCEEDED(hr)) 
     { 
      printf("WaveIn ID: %d\n", var.lVal); 
      VariantClear(&var); 
     } 

     hr = pPropBag->Read(L"DevicePath", &var, 0); 
     if (SUCCEEDED(hr)) 
     { 
      // The device path is not intended for display. 
      printf("Device path: %S\n", var.bstrVal); 
      VariantClear(&var); 
     } 

    } 
    return 0; 
} 

CComPtr<IMoniker> pMoniker = NULL; 
CComPtr<IMoniker> pMoniker2 = NULL; 
    CComPtr<IEnumMoniker> pEnum = NULL; 

    hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum); 
//pEnum->Next(1, &pMoniker,&cFetched); 

    if (SUCCEEDED(hr)) 
    { 
     DisplayDeviceInformation(pEnum, pMoniker);  
    } 
    pEnum = NULL; 
    hr = EnumerateDevices(CLSID_AudioInputDeviceCategory, &pEnum); 
    //pEnum->Next(1, &pMoniker2,&cFetched); 
    if (SUCCEEDED(hr)) 
    { 
     DisplayDeviceInformation(pEnum, pMoniker); 
    } 

Basiclly, первый DisplayDeviceInformation(pEnum, pMoniker); дает р == 0 ошибка. Если я однако раскомментирую pEnum->Next(1, &pMoniker,&cFetched);, он работает. С необработанными указателями мне не нужно это делать, поскольку код просто переходит к следующему устройству. Любые советы или помощь сделают меня очень благодарным, спасибо заранее!

ответ

1

Где CComPtr дает вам отказ, вы, вероятно, будете иметь проблему с необработанными указателями. Вы просто не предварительно предупреждены, и проблема возникает позже, например. как эталонная утечка.

  1. Вы, кажется, не нужно IMoniker в глобальном масштабе
  2. Вы должны очистить IMoniker указатель перед подачей его на счетчику

Смотрите ниже:

int DisplayDeviceInformation(IEnumMoniker* pEnum, IMoniker** ppSelectedMoniker) 
{ 
    CComPtr<IMoniker> pMoniker; 
    while (pEnum->Next(1, &pMoniker, NULL) == S_OK) 
    { 
     CComPtr<IPropertyBag> pPropBag; // You need it clear to start from for every moniker 
     HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag)); 
     // ... 
     if(we should stop enumeration and we are good with current moniker) 
     { 
      //ATLASSERT(ppSelectedMoniker != NULL); 
      *ppSelectedMoniker = pMoniker.Detach(); 
      return ... 
     } 
     // ... 
     pMoniker.Release(); // You have to do this, so that next Next would accept empty CComPtr as an argument 
    } 
    return 0; 
} 

CComPtr<IEnumMoniker> pEnumVideoMoniker; 
CComPtr<IMoniker> pSelectedVideoMoniker; 
hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnumVideoMoniker); 
if (SUCCEEDED(hr)) 
    DisplayDeviceInformation(pEnumVideoMoniker, &pSelectedVideoMoniker);  
CComPtr<IEnumMoniker> pEnumAudioMoniker; 
CComPtr<IMoniker> pSelectedAudioMoniker; 
hr = EnumerateDevices(CLSID_AudioInputDeviceCategory, &pEnumAudioMoniker); 
if (SUCCEEDED(hr)) 
    DisplayDeviceInformation(pEnumAudioMoniker, &pSelectedAudioMoniker); 
+0

Я должен, вероятно, упомянул, что позже я хочу использовать возвращенный pMoniker для BindToObject, если он найдет устройство. \t \t ч = pMoniker-> BindToObject (0, 0, IID_IBaseFilter (пустота **) &pSrc); \t \t ч = pGraph-> AddFilter (КРОУ, L "VidCap");. –

+0

См обновленный код выше –

+0

Ааа, спасибо много для уточнения это! –

Смежные вопросы