Part 1
The method wants to give you back a pointer to an object.
An IDirect3DIndexBuffer9 *.
Internally it is going to allocate an object and set the pointer you give it to that pointer.
Look at this:
void GiveYouMyPointer( IDirect3DIndexBuffer9 * _pd3dib9Out ) {
IDirect3DIndexBuffer9 * pd3dib9Allocated = new IDirect3DIndexBuffer9();
_pd3dib9Out = pd3dib9Allocated;
}
IDirect3DIndexBuffer9 * pd3dib9IndexBuffer = NULL;
GiveYouMyPointer( pd3dib9IndexBuffer );
What is pd3dib9IndexBuffer after this?
The answer is NULL. GiveYouMyPointer() changed a copy of your pointer. It didn’t actually make your pointer point to anything else.
There are 2 ways to do that correctly:
void GiveYouMyPointer( IDirect3DIndexBuffer9 * &_pd3dib9Out ) {
IDirect3DIndexBuffer9 * pd3dib9Allocated = new IDirect3DIndexBuffer9();
_pd3dib9Out = pd3dib9Allocated;
}
Now your pointer is passed as a reference, so changing it inside GiveYouMyPointer() actually changes your pointer from NULL to something else.
void GiveYouMyPointer( IDirect3DIndexBuffer9 ** _pd3dib9Out ) {
IDirect3DIndexBuffer9 * pd3dib9Allocated = new IDirect3DIndexBuffer9();
(*_pd3dib9Out) = pd3dib9Allocated;
}
This is exactly the same as passing by reference, except it requires a manual dereference inside GiveYouMyPointer(). Either way it is able to modify the pointer you actually passed it from NULL to something else.
This is what is happening inside those methods and why you have to pass things that way. Microsoft just chose to use 2 pointers instead of a reference.
Part 2
So why does this not work?
IDirect3DIndexBuffer9 ** ppd3dib9IndexBuffer = NULL;
GiveYouMyPointer( ppd3dib9IndexBuffer );
Because:
void GiveYouMyPointer( IDirect3DIndexBuffer9 ** _pd3dib9Out ) {
IDirect3DIndexBuffer9 * pd3dib9Allocated = new IDirect3DIndexBuffer9();
(*_pd3dib9Out) = pd3dib9Allocated; // ERROR: First pointer points to NULL/garbage. Bad dereference.
// Same as (*NULL) = pd3dib9Allocated;
}
L. Spiro