shared pointer instead of CComPtr, How to release()?

Started by
16 comments, last by Tispe 10 years, 8 months ago

Hi

I want to create an array of vertex buffers using std::shared_ptr. How can set the deleter to the ::Release() member? I need this so I can InstBuffers.clear() before resetting the device.


for(int i=0;i<1024;i++){
		std::shared_ptr<LPDIRECT3DVERTEXBUFFER9> spNewBuffer(new LPDIRECT3DVERTEXBUFFER9/*, std::mem_fun_ref(IDirect3DVertexBuffer9::Release())*/);
		LPDIRECT3DVERTEXBUFFER9 pTempBuf = *spNewBuffer.get();

		hr = d3ddev->CreateVertexBuffer(BufferSize, D3DUSAGE_DYNAMIC, NULL, D3DPOOL_DEFAULT, &pTempBuf, NULL);

		if( hr!=D3D_OK ){
			MessageBox(NULL, L"Failed to make buffer", L"Error", MB_OK);
			return false;
		} else {
			InstBuffers.push_back(spNewBuffer);
		}
	}
Advertisement

Pass a function that calls Release as the second argument to the shared pointer.

std::shared_ptr<T> a(new T, [](T *ptr) {ptr->Release();});

I get a red line ..[](LPDIRECT3DVERTEXBUFFER9 *ptr){ptr->Release();}...


std::shared_ptr<LPDIRECT3DVERTEXBUFFER9> spNewBuffer(new LPDIRECT3DVERTEXBUFFER9, [](LPDIRECT3DVERTEXBUFFER9 *ptr){ptr->Release();});
error C2227: left of '->Release' must point to class/struct/union/generic type
1> type is 'LPDIRECT3DVERTEXBUFFER9 *'

It's already a pointer... windows with its LP at the start of a name => it's already a pointer (EDIT: So a LPDIRECT3DVERTEXBUFFER9* is actually a DIRECT3DVERTEXBUFFER9**)

That means you don't want the shared pointer to be of type LPDIRECT3DVERTEXBUFFER9 either, it wants to be a DIRECT3DVERTEXBUFFER9.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Seems like shared_ptr dont like COM interfaces


std::shared_ptr<IDirect3DVertexBuffer9> spNewBuffer(new IDirect3DVertexBuffer9, [](IDirect3DVertexBuffer9 *ptr){ptr->Release();} );

Gives errors:

error C2259: 'IDirect3DVertexBuffer9' : cannot instantiate abstract class
1> due to following members:
1> 'HRESULT IDirect3DVertexBuffer9::QueryInterface(const IID &,void **)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1478) : see declaration of 'IDirect3DVertexBuffer9::QueryInterface'
1> 'ULONG IDirect3DVertexBuffer9::AddRef(void)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1479) : see declaration of 'IDirect3DVertexBuffer9::AddRef'
1> 'ULONG IDirect3DVertexBuffer9::Release(void)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1480) : see declaration of 'IDirect3DVertexBuffer9::Release'
1> 'HRESULT IDirect3DVertexBuffer9::GetDevice(IDirect3DDevice9 **)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1483) : see declaration of 'IDirect3DVertexBuffer9::GetDevice'
1> 'HRESULT IDirect3DVertexBuffer9::SetPrivateData(const GUID &,const void *,DWORD,DWORD)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1484) : see declaration of 'IDirect3DVertexBuffer9::SetPrivateData'
1> 'HRESULT IDirect3DVertexBuffer9::GetPrivateData(const GUID &,void *,DWORD *)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1485) : see declaration of 'IDirect3DVertexBuffer9::GetPrivateData'
1> 'HRESULT IDirect3DVertexBuffer9::FreePrivateData(const GUID &)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1486) : see declaration of 'IDirect3DVertexBuffer9::FreePrivateData'
1> 'DWORD IDirect3DVertexBuffer9::SetPriority(DWORD)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1487) : see declaration of 'IDirect3DVertexBuffer9::SetPriority'
1> 'DWORD IDirect3DVertexBuffer9::GetPriority(void)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1488) : see declaration of 'IDirect3DVertexBuffer9::GetPriority'
1> 'void IDirect3DVertexBuffer9::PreLoad(void)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1489) : see declaration of 'IDirect3DVertexBuffer9::PreLoad'
1> 'D3DRESOURCETYPE IDirect3DVertexBuffer9::GetType(void)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1490) : see declaration of 'IDirect3DVertexBuffer9::GetType'
1> 'HRESULT IDirect3DVertexBuffer9::Lock(UINT,UINT,void **,DWORD)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1491) : see declaration of 'IDirect3DVertexBuffer9::Lock'
1> 'HRESULT IDirect3DVertexBuffer9::Unlock(void)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1492) : see declaration of 'IDirect3DVertexBuffer9::Unlock'
1> 'HRESULT IDirect3DVertexBuffer9::GetDesc(D3DVERTEXBUFFER_DESC *)' : is abstract
1> c:\program files (x86)\microsoft directx sdk (june 2010)\include\d3d9.h(1493) : see declaration of 'IDirect3DVertexBuffer9::GetDesc'

That's because you can't create an IDirect3DVertexBuffer9 using new IDirect3DVertexBuffer9 (it's an abstract class).

How do you normally create an IDirect3DVertexBuffer9 derived object?

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

This seems to compile:


std::shared_ptr<LPDIRECT3DVERTEXBUFFER9> spNewBuffer(new LPDIRECT3DVERTEXBUFFER9, [](LPDIRECT3DVERTEXBUFFER9 (*ptr)){(*ptr)->Release();} );

Then you are creating an object of type

IDirect3DVertexBuffer9**

which probably isn't what you want...

EDIT:

shared_pointer<T> sp(new T);

creates a shared pointer to a T. You are effectively doing this in the above post:

shared_pointer<T*> sp(new T*);

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Right, I get a runtime error when InstBuffers.clear();

Unhandled exception at 0x778815de in Game.exe: 0xC0000005: Access violation reading location 0xcdcdcdcd.


private:
	virtual void _Destroy()
		{	// destroy managed resource
		_Dtor(_Ptr);
		}

Should I just wrap everything in a class and release in the destructor, or do you have better ideas?

I want to create a shared pointer to the vertex buffer or shared pointer to the pointer to the vertex buffer.

The creation and attaching the actual buffer to the last pointer on the chain is done further down in code


d3ddev->CreateVertexBuffer(BufferSize, D3DUSAGE_DYNAMIC, NULL, D3DPOOL_DEFAULT, &pTempBuf, NULL);

This topic is closed to new replies.

Advertisement