COM problems

D

dragonslayer008

I am trying to initialize Direct3D 9 in a C++/CLR application.
However, the create device function gives me a compilation error:

error C2664: 'IDirect3D9::CreateDevice' : cannot convert parameter 6
from 'cli::interior_ptr<Type>' to 'IDirect3DDevice9 **'
1> with
1> [
1> Type=IDirect3DDevice9 *
1> ]
1> Cannot convert a managed type to an unmanaged type

The code giving the error:

HRESULT hr;
hr = pd3dObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, pd3dPP, &pd3dDevice);

I thought a managed C++ class can have pointers to unmanaged code?
 
D

dragonslayer008

Hmm I managed to get this error to go away by doing the following:

I put the code in an unmanaged class UC. Then I added a pointer to UC
to a managed class. Any explanation of why this works?
 
D

dragonslayer008

I am trying to initialize Direct3D 9 in a C++/CLR application.
However, the create device function gives me a compilation error:

error C2664: 'IDirect3D9::CreateDevice' : cannot convert parameter 6
from 'cli::interior_ptr<Type>' to 'IDirect3DDevice9 **'
1> with
1> [
1> Type=IDirect3DDevice9 *
1> ]
1> Cannot convert a managed type to an unmanaged type

The code giving the error:

HRESULT hr;
hr = pd3dObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, pd3dPP, &pd3dDevice);

I thought a managed C++ class can have pointers to unmanaged code?


After more experimenting, I found that this works:

pin_ptr<IDirect3DDevice9*> p = &pd3dDevice;

HRESULT hr;
hr = pd3dObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
(HWND)hwnd.ToPointer(),
D3DCREATE_SOFTWARE_VERTEXPROCESSING, pd3dPP, p);

Why though? Isn't pd3dDevice (which is a data member of a ref class)
unmanaged since I'm using * syntax? I don't see why I have to pin
down an unmanaged pointer...
 
B

Ben Voigt [C++ MVP]

Hmm I managed to get this error to go away by doing the following:

I put the code in an unmanaged class UC. Then I added a pointer to UC
to a managed class. Any explanation of why this works?

Because when the pointer was inside the managed class, it would be moved
around by the garbage collector. Now it's in the native heap and won't be
moved.

pin_ptr would have worked equally well.
 
B

Ben Voigt [C++ MVP]

I am trying to initialize Direct3D 9 in a C++/CLR application.
However, the create device function gives me a compilation error:

error C2664: 'IDirect3D9::CreateDevice' : cannot convert parameter 6
from 'cli::interior_ptr<Type>' to 'IDirect3DDevice9 **'
1> with
1> [
1> Type=IDirect3DDevice9 *
1> ]
1> Cannot convert a managed type to an unmanaged type

The code giving the error:

HRESULT hr;
hr = pd3dObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, pd3dPP, &pd3dDevice);

I thought a managed C++ class can have pointers to unmanaged code?


After more experimenting, I found that this works:

pin_ptr<IDirect3DDevice9*> p = &pd3dDevice;

HRESULT hr;
hr = pd3dObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
(HWND)hwnd.ToPointer(),
D3DCREATE_SOFTWARE_VERTEXPROCESSING, pd3dPP, p);

Why though? Isn't pd3dDevice (which is a data member of a ref class)
unmanaged since I'm using * syntax? I don't see why I have to pin
down an unmanaged pointer...

Because the address of any data, no matter whether it's an integer, managed
handle, or unmanaged pointer, which is a member of a managed data type can
change because .NET uses a compacting garbage collector.

So you tell D3D, create a device, put the pointer to it *here*... but by the
time D3D gets done, *here* has changed and D3D doesn't know it.
 
B

Ben Voigt [C++ MVP]

I am trying to initialize Direct3D 9 in a C++/CLR application.
However, the create device function gives me a compilation error:

error C2664: 'IDirect3D9::CreateDevice' : cannot convert parameter 6
from 'cli::interior_ptr<Type>' to 'IDirect3DDevice9 **'
1> with
1> [
1> Type=IDirect3DDevice9 *
1> ]
1> Cannot convert a managed type to an unmanaged type

The code giving the error:

HRESULT hr;
hr = pd3dObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, pd3dPP, &pd3dDevice);

I thought a managed C++ class can have pointers to unmanaged code?


After more experimenting, I found that this works:

pin_ptr<IDirect3DDevice9*> p = &pd3dDevice;

HRESULT hr;
hr = pd3dObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
(HWND)hwnd.ToPointer(),
D3DCREATE_SOFTWARE_VERTEXPROCESSING, pd3dPP, p);

Why though? Isn't pd3dDevice (which is a data member of a ref class)
unmanaged since I'm using * syntax? I don't see why I have to pin
down an unmanaged pointer...

This would work too:

IDirect3DDevice9* tempDevice;
HRESULT hr;
hr = pd3dObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
(HWND)hwnd.ToPointer(), D3DCREATE_SOFTWARE_VERTEXPROCESSING, &tempDevice,
p);
pd3dDevice = tempDevice;

Because variables on the stack don't take part in compaction.
 

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