-2

I'm an absolute zero at C++. But I need to write a small c++ class for managing a d3ddevice. My C# code is:

public class HCPPUtils
{ 
    [DllImport("HSpectrum\\Assets\\HCPPUtils.dll")]
    private static extern int Getd3Device(ICanvasResourceCreator resourceCreator);}
    HCPPUtils hcp = new HCPPUtils();
    var pnt =  hcp.HGetOrCreate(ResourceCreator);
    var d3dDevice = SharpDX.Direct3D11.Device.FromPointer<SharpDX.Direct3D11.Device>(new System.IntPtr(pnt));

My C++ code is:

extern "C"
{
     __declspec(dllexport) int Getd3Device
    (Microsoft::Graphics::Canvas::ICanvasResourceCreator^ canvasDevice)
    {
         ComPtr<ID3D11Device> m_device;
         __abi_ThrowIfFailed(Windows::Graphics::DirectX::Direct3D11::GetDXGIInterface(canvasDevice->Device,m_device.GetAddressOf()));
          return m_device???
    }
}

How can i return a IntPtr from C++ code; so, how can i get IntPtr from ComPtr < ID3D11Device >?

[edited]

What I'm doing is... I have a win2d canvasandimatedcontrol in my c# project. I want to draw direct3d object in it using sharpdx. But I found out that I need to have the d3ddevice object from win2d canvas. And there isn't a c# method to get it. So the only solution I can imagine is to build a simple c++ project to which I can pass the canvas control and get the d3ddevice. The only problem is how to pass back the d3d device to c#. Sharp DX seems to have just a method Device.FormIntPtr to create it. But I'm not able to pass back the intptr to the c# object.

I tried to implement what Rook wrote, but I cannot understand how it could be useful for my scenario. I mean it could be usueful, but I need to pass the IDirect3DDevice object from a c++ project anyway.

puckkk
  • 11
  • 4
  • If my answer was inadequate, you could say so and it might get altered. If it was helpful, you should consider marking it as accepted. – Rook Mar 05 '16 at 16:39
  • Sorry for not replaying earlier, but I'm still looking for a way to do what I meant. Your answer wasn't inadequate. It was useful about reading a bit more about the argument... – puckkk Mar 07 '16 at 07:48
  • @Rook Added info in the original post :) – puckkk Mar 07 '16 at 08:03

2 Answers2

0

I suspect what you need to do is to read the docs for things like this: http://microsoft.github.io/Win2D/html/M_Microsoft_Graphics_Canvas_CanvasDevice_CreateFromDirect3D11Device.htm

CanvasDevice implements ICanvasResourceCreator, so you could return it directly once you've created it using the static factory method.

Be careful with the scope and lifetime of m_device here, because you don't want its refcount to be decremented when Getd3Device returns and the ComPtr goes out of scope. I'm assuming that it is actually part of a class that will look after its lifetime, but it bears repeating just in case.

Rook
  • 5,734
  • 3
  • 34
  • 43
0

I've been trying to access the unity3d device today. This is how I passed the pointer back into unity/managed code:

cpp:

/*
delegate to pass directx device/context back to managed code
see https://forum.unity3d.com/threads/communicating-c-with-c.89930/#post-586885
*/
typedef int(__stdcall *ANSWERCB)(ID3D11Device* ptr);
static ANSWERCB cb;

extern "C" __declspec(dllexport) int GetDevice(ANSWERCB fp)
{
    cb = fp;
    if (cb)
    {
        return cb(s_CurrentAPI->GetDevice());
    }
    return 0;
}

cs:

[DllImport("RenderingPlugin")]
private static extern void GetDevice(Action<IntPtr> callback);

later I call:

GetDevice(devicePtr =>
{
    Debug.Log(devicePtr);
    if (devicePtr == IntPtr.Zero) return;
    device = SharpDX.Direct3D11.Device.FromPointer<SharpDX.Direct3D11.Device>(devicePtr);

...

works fine in the editor as well as the built in the new 2017.1 beta version (as long as you copy the necessary 64bit system dlls to unitys plugin folder)

marw
  • 17
  • 1
  • 5