我正在尝试在c ++中创建(并填充)D3D11Buffer,通过互操作将指针传递给c#,以便使用slimdx从该缓冲区读取数据-应该不涉及通过cpu的缓冲区副本。
到目前为止,这是我的代码
函数导出:
extern "C" {__declspec(dllexport) HRESULT getValues(int * debug, ID3D11Buffer* bufOut); }
和功能:
ID3D11Device* d3d11Device;
ID3D11Buffer* triangleVertBuffer;
ID3D11DeviceContext* d3d11DevCon;
struct Vertex //Overloaded Vertex Structure
{
Vertex() {}
Vertex(float x, float y, float z)
: pos(x, y, z) {}
XMFLOAT3 pos;
};
HRESULT getValues(int * debug, ID3D11Buffer* bufOut) {
//Create the vertex buffer
Vertex v[] =
{
Vertex(0.0f, 0.5f, 0.5f),
Vertex(0.5f, -0.5f, 0.5f),
Vertex(-0.5f, -0.5f, 0.5f),
};
D3D_FEATURE_LEVEL FeatureLevelsRequested = D3D_FEATURE_LEVEL_11_0;
UINT numLevelsRequested = 1;
D3D_FEATURE_LEVEL FeatureLevelsSupported;
//create device
hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, &FeatureLevelsRequested, numLevelsRequested, D3D11_SDK_VERSION, &d3d11Device, &FeatureLevelsSupported, &d3d11DevCon);
debug[0] = hr;
D3D11_BUFFER_DESC vertexBufferDesc;
ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.ByteWidth = sizeof(Vertex) * 3;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vertexBufferData;
ZeroMemory(&vertexBufferData, sizeof(vertexBufferData));
vertexBufferData.pSysMem = v;
hr2 = d3d11Device->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &triangleVertBuffer);
bufOut = triangleVertBuffer;
debug[1] = hr2;
return hr;
}
在C#中,我像这样导入函数:
[System.Runtime.InteropServices.DllImport("CreateID3D11Buffer.dll", CallingConvention = CallingConvention.StdCall)]
private static unsafe extern UInt32 getValues([In, Out] int[] debug, [In, Out] IntPtr bufIn);
然后这样称呼它:
int[]debug = new int[2];
IntPtr bufPtr;// = IntPtr.Zero;
UInt32 hr = getValues(debug, bufPtr);
DataStream ds = new DataStream(bufPtr, sizeof(Vector3) * 3, true, false);
到目前为止一切顺利....现在解决我的问题(对我来说,仍然是C ++的初学者和C#的中级技能...):
它不起作用:在c#中,最后一行DataStream构造函数引发错误,因为bufPtr(到非托管内存的IntPtr)为null。因此,显然,p / invoke或我的c ++代码有问题...因此,我查看了c ++中dx11函数的结果->
HRESULT:我在c#中导入的函数的返回值hr等于0,但是调试数组中的两个元素都等于-1!一方面,我不了解如何在此处解释负值,另一方面,返回值hr应该至少等于debug [0](我知道它们的类型有所不同)?所以,我不知道该怎么做,但这表明函数D3D11CreateDevice()出现问题,然后d3d11Device-> CreateBuffer()也出现问题。
我不确定我是否正确理解了slimdx的DataStream构造函数-指向非托管内存的IntPtr指向图形内存,或者这是从非托管CPU内存读取的函数?不幸的是,我找不到使用IntPtr重载的任何示例...这是文档:https://slimdx.org/docs/html/M_SlimDX_DataStream__ctor_2.htm
所以,我做错了吗? :)如果是这样,请指出正确的方向。
注意:大多数cpp代码是从https://www.braynzarsoft.net/viewtutorial/q16390-4-begin-drawing中提取的
感谢您的任何帮助/提示,已经尝试了好几天了。
最佳答案
ID3D11Buffer*
是一个指针。如果要获取指针,则必须将指针传递给指针,因此,请按以下方式定义C ++方法:
HRESULT getValues(int * debug, ID3D11Buffer** bufOut)
{
...
*bufOut = triangleVertBuffer;
...
}
和C#像这样:
[DllImport("CreateID3D11Buffer.dll", CallingConvention = CallingConvention.StdCall)]
private static extern int getValues([In, Out] int[] debug, out IntPtr bufIn);
这部分应该起作用。