2014-03-14 28 views
0

我不知道如何使用雙指針。理解和使用雙指針的問題

功能我需要使用的外觀如下:

HRESULT GetBuffer(
    [out] IMediaSample **ppBuffer, 
    [in] REFERENCE_TIME *pStartTime, 
    [in] REFERENCE_TIME *pEndTime, 
    [in] DWORD dwFlags 
); 

文件說:

ppBuffer [出]

接收指向緩衝區的IMediaSample接口。調用者必須釋放該接口。

這是我嘗試使用它:

HRESULT MCMyOutputPin::Deliver(IMediaSample* sample) 
{ 
    HRESULT hr = NO_ERROR; 
    myLogger->LogDebug("In Outputpin Deliver", L"D:\\TEMP\\yc.log"); 
    if (sample->GetActualDataLength() > 0) 
    { 
     IMediaSample **outsample; 



     m_pAllocator->GetBuffer(outsample, NULL, NULL, NULL); //Access violation here 
     BYTE** sampleBuffer; 
     BYTE** newBuffer; 
     sample->GetPointer(sampleBuffer); 

     (*outsample)->GetPointer(newBuffer); 

     memcpy((void *)newBuffer, (void *)sampleBuffer, sizeof(**sampleBuffer)); 

     m_pInputPin->Receive(*outsample); 

     sample->AddRef(); 
    } 

    return hr; 
    //Forward to filter 
} 

這給了我一個:

訪問衝突讀取位置0xFFFFFFFFFFFFFFFF。

然後我嘗試使用地址運算符:

hr = m_pAllocator->GetBuffer(&outsample, NULL, NULL, NULL); //outsample is set to NULL 
    BYTE* sampleBuffer = NULL; 
    BYTE* newBuffer = NULL; 
    sample->GetPointer(&sampleBuffer); 

    outsample->GetPointer(&newBuffer); 

    memcpy((void *)newBuffer, (void *)sampleBuffer, sizeof(*sampleBuffer)); 

    m_pInputPin->Receive(outsample); 

這臺outsample爲NULL。

那麼,處理雙指針的正確語法是什麼?

回答

2

我的第一個高級評論是,你沒有檢查你調用的函數的返回值。忽略錯誤檢查是錯誤的。你的第一步是添加必要的錯誤檢查。


HRESULT GetBuffer(
    [out] IMediaSample **ppBuffer, 
    [in] REFERENCE_TIME *pStartTime, 
    [in] REFERENCE_TIME *pEndTime, 
    [in] DWORD dwFlags 
); 

第一參數用於一個IMediaSample*返回給調用者。需要聲明IMediaSample*類型的變量,並通過其地址:

IMediaSample* sample; 
.... 
hr = m_pAllocator->GetBuffer(&outsample, ...); 
// check hr 
.... 

所以,outsampleIMediaSample*類型。當你的地址爲&outsample時,你現在有一些類型IMediaSample**,這就是你需要的。

請記住,使用接口時,您總是使用指向接口的指針。


您在BYTE**參數中犯了同樣的錯誤。再次聲明類型BYTE*的變量,並將這些變量的地址傳遞給您調用的函數。

BYTE* sampleBuffer; 
BYTE* newBuffer; 
.... 
hr = sample->GetPointer(&sampleBuffer); 
// check hr 
hr = outsample->GetPointer(newBuffer); 
// check hr 

使用你的電話sizeof(**sampleBuffer)memcpy是錯誤的。在你的代碼,其中sampleBuffer被錯誤宣佈爲BYTE**sizeof(**sampleBuffer)只是sizeof(BYTE)這始終是1

事實上,你可以得出這樣的結論,因爲sizeof在編譯時評估的任何使用sizeof是不正確這裏。您需要使用這些接口提供的任何功能在運行時查找動態緩衝區的實際大小。


致電sample->AddRef()看起來有點懷疑。我沒有看到任何證據表明任何事物都對界面有了新的參考。

1
IMediaSample **outsample; 

    m_pAllocator->GetBuffer(outsample, NULL, NULL, NULL); 

你傳遞函數的價值outsample,這是一個垃圾值,因爲它沒有指向任何東西。你想:

IMediaSample *outsample; 

    m_pAllocator->GetBuffer(&outsample, NULL, NULL, NULL); 

這使功能的outsample地址,以便它可以東西,它希望在它返回的指針。

0

我嘗試模擬函數作爲測試,它使用int **作爲輸出。這裏的問題是功能是假設*輸出是有效的,所以在第一種方式,你必須確保,你可能想要做的事,因爲這

sample = new IMediaSample[1] 

這是我的示例代碼,希望它幫助

#include <iostream> 

using namespace std; 

void test(int** output ,int* in) 
{ 
    *output = new int[1]; 
    output[0][0] = in[0]; 
} 
int main() 
{ 
    int a[] ={ 2 }; 
    int* out1; 
    test(&out1 ,a); 
    cout << out1[0] << endl; 
    int** out2; 
    out2 = new int*[1]; 
    test(out2 ,a); 
    cout << out2[0][0] << endl; 

    return 0; 
} 
+0

你真的不想這樣做:'sample = new IMediaSample [1];' –