-2

There is this function that requires a **ID3D11Buffer (where vertexBuffer.get() currently is). I have the following code:

shared_ptr<ID3D11Buffer> vertexBuffer;
this->graphicContext->GetDevice()->CreateBuffer( &bd, &srd, vertexBuffer.get() );

argument of type "ID3D11Buffer *" is incompatible with parameter of type "ID3D11Buffer **"

How would i get a pointer to a pointer? vertexBuffer.get() just returns a pointer

Jimmyt1988
  • 20,466
  • 41
  • 133
  • 233
  • Is there anything i can add to clarify my question? – Jimmyt1988 Sep 10 '15 at 01:10
  • An explanation of *why* the function requires a `**ID3D11Buffer` would help. For example, does it create one if one doesn't exist? Or does it always replace the buffer with a new one? Or what? – David Schwartz Sep 10 '15 at 01:17
  • 1
    Usually when you see something like that, the function is going to create and return the buffer for you buy updating the given pointer. That hints there's likely a DeleteBuffer out there to perform clean-up. If that's the case, you do not want to automate the destruction logic with a stock smart pointer. At the very least you'll want to provide a deleter to handle the specialized destruction. – user4581301 Sep 10 '15 at 01:19
  • Looks like `ID3D11Buffer` is a COM interface (https://msdn.microsoft.com/en-us/library/windows/desktop/ff476351%28v=vs.85%29.aspx). – beerboy Sep 10 '15 at 02:19
  • 1
    Shouldn't you be using `CCOMPtr` or something instead of `shared_ptr`? I'm sure you can get the latter to do what you want, but when there are purpose built alternatives, why bother? If you must use `shared_ptr`, I'd go with beerboy's answer and use a raw pointer to begin with, create the buffer, and transfer ownership to the `shared_ptr`. – Praetorian Sep 10 '15 at 03:31

2 Answers2

3

You have to acquire the buffer into a raw pointer:

ID3D11Buffer* vbptr;
HRESULT hr = this->graphicContext->GetDevice()->CreateBuffer( &bd, &srd, &vbptr);
IF(FAILED(hr))
{
    // an error occurred...
}

Then assign it correctly to a shared_ptr with a custom deleter that calls Release:

std::shared_ptr<ID3D11Buffer> vertexBuffer(vbptr, &ID3D11Buffer::Release);
beerboy
  • 1,304
  • 12
  • 12
-1

It's not clear what the semantics of CreateBuffer is or why you would be passing it a buffer that already exists.

ID3D11Buffer* buf = vertexBuffer.get();
this->graphicContext->GetDevice()->CreateBuffer( &bd, &srd, &buf);
if (buf != vertexBuffer.get())
    vertexBuffer = new shared_ptr<ID3D11Buffer> (buf);

This requires ID3D11Buffer to have a constructor that takes ownership of an ID3D11Buffer *. Without that, this will only work if the function never creates a buffer and only takes an ID3D11Buffer ** so it can create one if one doesn't already exist.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • @beerboy That's correct if `ID3D11Buffer` doesn't have a proper destructor. But if that's so, I'd prefer wrapping it in an RAII class with a proper destructor rather than constructing the `shared_ptr` differently. – David Schwartz Sep 10 '15 at 02:43
  • For COM objects like ``ID3D11Buffer``, don't use ``std::shared_ptr``. Use ``Microsoft::WRL::ComPtr``. – Chuck Walbourn Sep 10 '15 at 07:46