سؤال

I am not sure how to use double pointers.

The function i need to use looks as following:

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

Documentation says:

ppBuffer [out]

Receives a pointer to the buffer's IMediaSample interface. The caller must release the interface.

This is what i tried using it:

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
}

Which gives me an:

Access violation reading location 0xFFFFFFFFFFFFFFFF.

Then i tried using the address operator:

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);

This sets outsample to NULL.

So what is the correct syntax to handle double pointers?

هل كانت مفيدة؟

المحلول

My first, high-level comment, is that you are not checking the return values of the functions that you call. It's a mistake to neglect error checking. Your first step is to add the necessary error checking.


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

The first parameter is used to return a IMediaSample* to the caller. You need to declare a variable of type IMediaSample*, and pass its address:

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

So, outsample is of type IMediaSample*. When you take its address, with &outsample, you now have something of type IMediaSample**, which is what you need.

Remember that when working with interfaces, you always work with a pointer to the interface.


You've made the same mistake with the BYTE** parameters. Again, declare variables of type BYTE*, and pass the address of these variables to the functions that you call.

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

Using sizeof(**sampleBuffer) in your call to memcpy is wrong. In your code, where sampleBuffer is wrongly declared as BYTE**, sizeof(**sampleBuffer) is just sizeof(BYTE) which is always 1.

In fact you can conclude that any use of sizeof is incorrect here because sizeof is evaluated at compile time. You need to find the actual size of the dynamic buffer at runtime using whatever functionality these interfaces provide.


The call to sample->AddRef() looks a little suspect. I don't see any evidence that anything has taken a new reference to the interface.

نصائح أخرى

    IMediaSample **outsample;

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

You're passing the function the value of outsample, which is a garbage value since it doesn't point to anything. You want:

    IMediaSample *outsample;

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

This gives the function the address of outsample so that it can stuff the pointer it wants to return in it.

I try to simulate the function as test, which using int** as output . the problem here is the function is suppose *output is is valid, so in the first way ,you have to make sure that, you might want to do something as this

 sample = new IMediaSample[1]

this is my sample code, hope it helps

 #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;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top