Closed gsuberland closed 1 year ago
Hi,
You're right. The real annotation we can see in dxgi1_2.h is this:
_Out_writes_bytes_to_(DirtyRectsBufferSize, *pDirtyRectsBufferSizeRequired) RECT *pDirtyRectsBuffer
Where _Out_writes
is somewhat an _In_
from a caller perspective. This was not handled correctly by the generator, so I've fixed it and commited the changes. But it won't use a tagRect, it's still an IntPtr.
You can redeclare it and use your version, or write an extension method in the spirit of DirectN that should logically go in IDXGIOutputDuplicationExtensions.cs
. I have written one but it's not commited since I can't test it right now:
public static tagRECT[] GetFrameDirtyRects(this IComObject<IDXGIOutputDuplication> output) => GetFrameDirtyRects(output?.Object);
public static tagRECT[] GetFrameDirtyRects(this IDXGIOutputDuplication duplication)
{
if (duplication == null)
throw new ArgumentNullException(nameof(duplication));
var hr = duplication.GetFrameDirtyRects(0, IntPtr.Zero, out var size);
if (size == 0)
{
hr.ThrowOnError(); // won't throw if no error
return Array.Empty<tagRECT>();
}
var rects = new List<tagRECT>(); // tagRect is DirectN provided
using (var mem = new ComMemory(size)) // this memory tool is DirectN provided
{
var rectSize = Marshal.SizeOf<tagRECT>();
var curSize = 0;
duplication.GetFrameDirtyRects(size, mem.Pointer, out size).ThrowOnError();
do
{
rects.Add(Marshal.PtrToStructure<tagRECT>(mem.Pointer + curSize));
curSize += rectSize;
}
while (curSize < size);
}
return rects.ToArray();
}
closed due to inactivity
The
GetFrameDirtyRects
andGetFrameMoveRects
methods inIDXGIOutputDuplication
are being auto-generated without IntPtr
arguments for the buffers:https://github.com/smourier/DirectN/blob/1de2dd5af5be6ddef098a18571806c815203d396/DirectN/DirectN/Generated/IDXGIOutputDuplication.cs#L30-L34
The MSDN documentation is vague on this, but Microsoft's examples (e.g. the
DuplicationManager
example) make it clear that a pointer to a pre-allocated buffer is supposed to be passed in, rather than the functions passing a pointer to a buffer back out. As such, these should beIntPtr
rather thanout IntPtr
.The correct signature would be:
Alternatively, it should be possible to do something like this to avoid having to use
Marshal
to do the alloc and structure copies:Although I've never done this with COM interop in particular, so it's possible there's some complexity I've overlooked in terms of array passing.
It could also be useful to add extension methods to automagically handle everything in a single call. Something along the lines of:
(plus the same kind of thing for
GetFrameMoveRects
)