理解和使用双指针的问题

时间:2014-03-14 09:36:54

标签: c++ directshow

我不知道如何使用双指针。

我需要使用的功能如下:

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

文档说:

  

ppBuffer [out]

     

接收指向缓冲区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);

这将outample设置为NULL。

那么处理双指针的正确语法是什么?

3 个答案:

答案 0 :(得分: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
....

因此,outsample的类型为IMediaSample*。当您使用&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 :(得分:1)

    IMediaSample **outsample;

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

你传递的函数是outsample,这是一个垃圾值,因为它没有指向任何东西。你想要:

    IMediaSample *outsample;

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

这为函数提供了outsample的地址,以便它可以填充它想要返回的指针。

答案 2 :(得分:0)

我尝试将函数模拟为test,使用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;
}