Direct3D

D

Dirk Schippers

Hi,

I'm sorry in advance for a possibly stupid question, but I'm very new to
..net.
I have old code in C++ that should be implemented in a .net environment.
The code has a class which creates a Direc3D object in the constructor
and releases the Direct3D object in the destructor.

class bar
{
public:
bar()
{
m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
}

~bar()
{
m_pD3D->Release();
}

private:
IDirect3D9 *m_pD3D;
};

Now I want to make this class garbage collected, so I change the class
to: ref class bar and instantiate it with gcnew.

But as I already know, the destructor will no longer be called, even
when the object is destroyed by the garbage collector (in this case,
when the program is closed). So my m_pD3D object will never be released.

The problem gets worse for the project when this happens to a CTexture
class which implements a IDirect3DTexture9* object that is released in
the destructor. Textures are created and released throughout the running
process.

Can anyone tell me how you can change this so that everything of directx
is also garbage collected?

Is there a way that I can change: IDirect3DTexture9 *m_pTex to
IDirect3DTexture9 ^m_pTex or something like that?

Or, how else should I handle the destruction code?

Thanks,
Dirk.
 
P

primeMover

Hi Dirk,

Dirk Schippers said:
Or, how else should I handle the destruction code?

Here's a good blog post, that explains, how C++/CLI implements the
disposable interface:
http://blogs.thinktecture.com/cnagel/archive/2006/04/10/414477.aspx

To simplify the usage of com smart pointers, I'm using
msclr::com::ptr

To simplify the usage of pointers to native resources, I'm using
CAutoNativePtr
See here:
http://www.codeproject.com/KB/mcpp/CAutoNativePtr.aspx

I can also recommend Nish's book "C++/CLI in Action". This saved me days of
searching for a solution...
 
A

Armin Zingler

Dirk said:
Hi,

I'm sorry in advance for a possibly stupid question, but I'm very new
to .net.
I have old code in C++ that should be implemented in a .net
environment. The code has a class which creates a Direc3D object in
the constructor and releases the Direct3D object in the destructor.

class bar
{
public:
bar()
{
m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
}

~bar()
{
m_pD3D->Release();
}

private:
IDirect3D9 *m_pD3D;
};

Now I want to make this class garbage collected, so I change the class
to: ref class bar and instantiate it with gcnew.

But as I already know, the destructor will no longer be called, even
when the object is destroyed by the garbage collector (in this case,
when the program is closed). So my m_pD3D object will never be
released.

The problem gets worse for the project when this happens to a CTexture
class which implements a IDirect3DTexture9* object that is released in
the destructor. Textures are created and released throughout the
running process.

Can anyone tell me how you can change this so that everything of
directx is also garbage collected?

Is there a way that I can change: IDirect3DTexture9 *m_pTex to
IDirect3DTexture9 ^m_pTex or something like that?

Or, how else should I handle the destruction code?

The finalizer is missing (!bar). Documentation:
http://msdn.microsoft.com/en-us/library/ms177197.aspx


(Incomplete) Example of one of my managed wrapper classes:

Declaration:
public ref class IndexBuffer
{
public:
IntPtr Lock(
UINT OffsetToLock,
UINT SizeToLock,
LockFlags Flags
);

void Unlock();

internal:
LPDIRECT3DINDEXBUFFER9 native;
IndexBuffer(LPDIRECT3DINDEXBUFFER9 native);
~IndexBuffer();
!IndexBuffer();
};

Implementation:
IndexBuffer::~IndexBuffer() {this->!IndexBuffer();}
IndexBuffer::!IndexBuffer() {this->native->Release();}


Armin
 
B

Ben Voigt [C++ MVP]

Armin said:
The finalizer is missing (!bar). Documentation:
http://msdn.microsoft.com/en-us/library/ms177197.aspx


(Incomplete) Example of one of my managed wrapper classes:

Declaration:
public ref class IndexBuffer
{
public:
IntPtr Lock(
UINT OffsetToLock,
UINT SizeToLock,
LockFlags Flags
);

void Unlock();

internal:
LPDIRECT3DINDEXBUFFER9 native;
IndexBuffer(LPDIRECT3DINDEXBUFFER9 native);
~IndexBuffer();
!IndexBuffer();
};

Implementation:
IndexBuffer::~IndexBuffer() {this->!IndexBuffer();}
IndexBuffer::!IndexBuffer() {this->native->Release();}

Does C++/CLI automatically class GC::SuppressFinalize(this), or is there a
chance of double free here? As well, there's nothing stopping a non-C++
client from calling Dispose more than once, so I think it is important to
add logic to avoid the double free.
 
A

Armin Zingler

Ben said:
Does C++/CLI automatically class GC::SuppressFinalize(this), or is
there a chance of double free here? As well, there's nothing
stopping a non-C++ client from calling Dispose more than once, so I
think it is important to add logic to avoid the double free.

You can be right. The example is incomplete, but thanks for the hint (for
Dirk in particular). Have to add this to my todo-list also.


Armin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top