COM problems

  • Thread starter Thread starter dragonslayer008
  • Start date Start date
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?
 
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?
 
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...
 
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.
 
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.
 
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.
 
Back
Top