从C+;很难编组结构的DirectX数组+;到C# 目标< /强>:将C++结构的指针(指向一个?)数组排列为C?
C++: C#:从C+;很难编组结构的DirectX数组+;到C# 目标< /强>:将C++结构的指针(指向一个?)数组排列为C?,c#,c++,marshalling,unmarshalling,sharpdx,C#,C++,Marshalling,Unmarshalling,Sharpdx,C++: C#: BeginScene(LPDIRECT3DDEVICE9 pDevice) BeginStateBlock(LPDIRECT3DDEVICE9 pDevice) Clear(LPDIRECT3DDEVICE9 pDevice, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) ColorFill(LPDIRECT3DDEVICE9 pDevice, IDirec
BeginScene(LPDIRECT3DDEVICE9 pDevice)
BeginStateBlock(LPDIRECT3DDEVICE9 pDevice)
Clear(LPDIRECT3DDEVICE9 pDevice, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil)
ColorFill(LPDIRECT3DDEVICE9 pDevice, IDirect3DSurface9* pSurface,CONST RECT* pRect,D3DCOLOR color)
CreateAdditionalSwapChain(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain9** pSwapChain)
CreateCubeTexture(LPDIRECT3DDEVICE9 pDevice, UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,HANDLE* pSharedHandle)
我使用来定义D3DVERTEXELEMENT9
结构。SharpDX是一个托管的DirectX库,因此它应该与COM互操作非常兼容。实际上,我已经有10个其他钩子工作得很好,但这是第一个使用指向结构数组的指针的钩子
为了防止SharpDX的结构定义不起作用,我还尝试用我自己的定义替换它:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class D3DVERTEXELEMENT9
{
public short Stream;
public short Offset;
public DeclarationType Type; // Enum
public DeclarationMethod Method; // Enum
public DeclarationUsage Usage; // Enum
public byte UsageIndex;
}
我尝试了以下C#方法签名:
注意:将IntPtr devicePointer
作为第一个参数应该不是问题。我已经为其他10个成功工作的钩子准备了它
注意:这些是Direct3D API挂钩。所以我的程序通过了我需要从非托管C++环境到托管C环境的数据。
1:
CreateVertexDeclaration(IntPtr设备指针,D3DVERTEXELEMENT9[]vertexElements,out IntPtr vertexDeclaration)
结果:数组有一个元素,但其值是默认值(没有意义)。这意味着short Stream
、short Offset
、Type
、Method
、Usage
和UsageIndex
都是0(枚举取其第一个值)
2:
CreateVertexDeclaration(IntPtr设备指针,参考D3DVERTEXELEMENT9[]顶点元素,输出IntPtr顶点声明)
结果:数组本身为空
3:
CreateVertexDeclaration(IntPtr设备指针,[In,Out]D3DVERTEXELEMENT9[]vertexElements,Out IntPtr vertexDeclaration)
与1相同。没有好处
4:
CreateVertexDeclaration(IntPtr devicePointer、D3DVERTEXELEMENT9 vertexElements、out IntPtr vertexDeclaration)
与1相同,没有任何变化。我得到一个默认的结构。如果我调用了newd3dvertexelement9()
,情况也一样
5:
CreateVertexDeclaration(IntPtr devicePointer,参考D3DVERTEXELEMENT9 vertexElements,out IntPtr vertexDeclaration)
我忘了结果,但没用。我想它实际上撞坏了钩子
6:
CreateVertexDeclaration(IntPtr设备指针、IntPtr顶点元素、out IntPtr顶点声明)
我认为这6或1/2应该是正确的。我可能把这个方法的实现搞砸了
我尝试将此代码用于它:
var vertex = (D3DVERTEXELEMENT9)Marshal.PtrToStructure(vertexElements, typeof(D3DVERTEXELEMENT9));
但它不起作用!和#1一样。指向结构的封送指针是一个默认结构,与调用new D3DVERTEXELEMENT9()
时相同
7:
CreateVertexDeclaration(IntPtr设备指针、ref IntPtr vertexElements、out IntPtr vertexDeclaration)
零或零;无效
对于方法6(使用IntPtr),我尝试在VisualStudio中查看内存区域。接下来大约50个字节都是零。在50个零的字段中可能有一个
2
字节。但是,从提供给该方法的IntPtr开始,几乎有49个字节的零
这不是个问题吗?这不意味着提供的指针已经不正确了吗?所以我认为这意味着我有错误的方法签名。问题是我一直在尝试各种可能的组合,它们要么使程序崩溃,要么给我一个默认数组,就像我调用了newd3dvertexelement9()
一样
问题:正确的将代码从.C++到C语言的代码包编排的解决方案是什么?为什么我当前的签名不正确?< /强> < /P>
附加注释:在C++中,这个特定数组的长度由我不知道在没有某种传递的长度参数的情况下,如何获得C#中相应的数组长度
其他工作挂钩:
BeginScene(LPDIRECT3DDEVICE9 pDevice)
BeginStateBlock(LPDIRECT3DDEVICE9 pDevice)
Clear(LPDIRECT3DDEVICE9 pDevice, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil)
ColorFill(LPDIRECT3DDEVICE9 pDevice, IDirect3DSurface9* pSurface,CONST RECT* pRect,D3DCOLOR color)
CreateAdditionalSwapChain(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain9** pSwapChain)
CreateCubeTexture(LPDIRECT3DDEVICE9 pDevice, UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,HANDLE* pSharedHandle)
C++:
BeginScene(LPDIRECT3DDEVICE9 pDevice)
BeginStateBlock(LPDIRECT3DDEVICE9 pDevice)
Clear(LPDIRECT3DDEVICE9 pDevice, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil)
ColorFill(LPDIRECT3DDEVICE9 pDevice, IDirect3DSurface9* pSurface,CONST RECT* pRect,D3DCOLOR color)
CreateAdditionalSwapChain(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain9** pSwapChain)
CreateCubeTexture(LPDIRECT3DDEVICE9 pDevice, UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,HANDLE* pSharedHandle)
C#:
BeginScene(LPDIRECT3DDEVICE9 pDevice)
BeginStateBlock(LPDIRECT3DDEVICE9 pDevice)
Clear(LPDIRECT3DDEVICE9 pDevice, DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil)
ColorFill(LPDIRECT3DDEVICE9 pDevice, IDirect3DSurface9* pSurface,CONST RECT* pRect,D3DCOLOR color)
CreateAdditionalSwapChain(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain9** pSwapChain)
CreateCubeTexture(LPDIRECT3DDEVICE9 pDevice, UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,HANDLE* pSharedHandle)
注意:我对所有这些代理使用SharpDX枚举和结构,它们工作正常。它们也都以IntPtr devicePointer
开头
BeginSceneDelegate(IntPtr devicePointer);
BeginStateBlocKDelegate(IntPtr devicePointer);
ClearDelegate(IntPtr devicePointer, int count, IntPtr rects, ClearFlags flags, ColorBGRA color, float z, int stencil);
ColorFillDelegate(IntPtr devicePointer, IntPtr surface, IntPtr rect, ColorBGRA color);
CreateAdditionalSwapChainDelegate(IntPtr devicePointer, [In, Out] PresentParameters presentParameters, out SwapChain swapChain);
CreateCubeTextureDelegate(IntPtr devicePointer, int edgeLength, int levels, Usage usage, Format format, Pool pool, out IntPtr cubeTexture, IntPtr sharedHandle);
...
为其他挂钩传递的参数日志:
DLL injection suceeded.
Setting up Direct3D 9 hooks...
Activating Direct3D 9 hooks...
CreateDepthStencilSurface(IntPtr devicePointer: 147414976, Int32 width: 1346, Int32 height: 827, Format format: D24S8, MultisampleType multiSampleType: None, Int32 multiSampleQuality: 0, Boolean discard: False, IntPtr& surface: (out), IntPtr sharedHandle: 0)
CreateDepthStencilSurface(IntPtr devicePointer: 147414976, Int32 width: 1346, Int32 height: 827, Format format: D24S8, MultisampleType multiSampleType: None, Int32 multiSampleQuality: 0, Boolean discard: False, IntPtr& surface: (out), IntPtr sharedHandle: 0)
Clear(IntPtr devicePointer: 147414976, Int32 count: 0, IntPtr rects: (Empty), ClearFlags flags: Target, ColorBGRA color: A:0 R:0 G:0 B:0, Single z: 1, Int32 stencil: 0)
Clear(IntPtr devicePointer: 147414976, Int32 count: 0, IntPtr rects: (Empty), ClearFlags flags: Target, ColorBGRA color: A:0 R:0 G:0 B:0, Single z: 1, Int32 stencil: 0)
BeginScene(IntPtr devicePointer: 147414976)
Clear(IntPtr devicePointer: 147414976, Int32 count: 0, IntPtr rects: (Empty), ClearFlags flags: Target, ColorBGRA color: A:0 R:0 G:0 B:0, Single z: 1, Int32 stencil: 0)
Clear(IntPtr devicePointer: 147414976, Int32 count: 0, IntPtr rects: (Empty), ClearFlags flags: Target, ColorBGRA color: A:0 R:0 G:0 B:0, Single z: 1, Int32 stencil: 0)
Clear(IntPtr devicePointer: 147414976, Int32 count: 0, IntPtr rects: (Empty), ClearFlags flags: ZBuffer, ColorBGRA color: A:0 R:0 G:0 B:0, Single z: 1, Int32 stencil: 0)
BeginScene(IntPtr devicePointer: 147414976)
与此CreateVertexDeclaration()
最相似的方法签名似乎是Clear()
。下面是我对Clear()
的实现:
private Result Clear(IntPtr devicePointer、int count、IntPtr rects、clearfagas、ColorBGRA color、float z、int stencil)
{
尝试
{
var structSize=Marshal.SizeOf(typeof(Rectangle));
var structs=新矩形[count];
for(int i=0;i
首先,SharpDX中的声明使用的是Pack=2(而不是Pack=1):
[StructLayout(LayoutKind.Sequential,Pack=2)]
公共部分结构顶点元素{
...
public unsafe static void CreateVertexDeclaration(IntPtr devicePointer, IntPtr vertexElementsPtr, out IntPtr vertexDeclaration)
{
var vertexElements = (VertexElement*)vertexElementsPtr;
// Access to all VertexElement (last element is specified by Cmacro D3DDECL_END() in d3d9types.h)
...
}