CsWin32 generates broken wrapper for ExtTextOut
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 2.5k
- Forks
- 124
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 9
Description
Actual behavior
Seems CsWin32 generates ReadOnlySpan where it should't:
I seening string lpString, ReadOnlySpan<int> lpDx where in original there is winmdroot.Foundation.PCWSTR lpString, uint c, [Optional] int* lpDx where c is The length of the string pointed to by lpString. but it get receives (uint )lpDx.Length in wrapper instead.
public static partial class PInvoke
{
/// <inheritdoc cref="ExtTextOut(winmdroot.Graphics.Gdi.HDC, int, int, winmdroot.Graphics.Gdi.ETO_OPTIONS, winmdroot.Foundation.RECT*, winmdroot.Foundation.PCWSTR, uint, int*)"/>
public static unsafe winmdroot.Foundation.BOOL ExtTextOut(SafeHandle hdc, int x, int y, winmdroot.Graphics.Gdi.ETO_OPTIONS options, winmdroot.Foundation.RECT? lprect, string lpString, ReadOnlySpan<int> lpDx)
{
bool hdcAddRef = false;
try
{
fixed (int* lpDxLocal = lpDx)
{
fixed (char* lpStringLocal = lpString)
{
winmdroot.Graphics.Gdi.HDC hdcLocal;
if (hdc is object)
{
hdc.DangerousAddRef(ref hdcAddRef);
hdcLocal = (winmdroot.Graphics.Gdi.HDC)hdc.DangerousGetHandle();
}
else
hdcLocal = default(winmdroot.Graphics.Gdi.HDC);
winmdroot.Foundation.RECT lprectLocal = lprect.HasValue ? lprect.Value : default(winmdroot.Foundation.RECT);
winmdroot.Foundation.BOOL __result = PInvoke.ExtTextOut(hdcLocal, x, y, options, lprect.HasValue ? &lprectLocal : null, lpStringLocal, (uint )lpDx.Length, lpDxLocal);
return __result;
}
}
}
finally
{
if (hdcAddRef)
hdc.DangerousRelease();
}
}
/// <summary>The ExtTextOut function draws text using the currently selected font, background color, and text color. You can optionally provide dimensions to be used for clipping, opaquing, or both.</summary>
/// <param name="hdc">A handle to the device context.</param>
/// <param name="x">The x-coordinate, in logical coordinates, of the reference point used to position the string.</param>
/// <param name="y">The y-coordinate, in logical coordinates, of the reference point used to position the string.</param>
/// <param name="options"></param>
/// <param name="lprect">A pointer to an optional <a href="https://docs.microsoft.com/windows/desktop/api/windef/ns-windef-rect">RECT</a> structure that specifies the dimensions, in logical coordinates, of a rectangle that is used for clipping, opaquing, or both.</param>
/// <param name="lpString">A pointer to a string that specifies the text to be drawn. The string does not need to be zero-terminated, since <i>cbCount</i> specifies the length of the string.</param>
/// <param name="c">
/// <para>The <a href="https://docs.microsoft.com/windows/desktop/gdi/specifying-length-of-text-output-string">length of the string</a> pointed to by <i>lpString</i>. This value may not exceed 8192.</para>
/// <para><see href="https://docs.microsoft.com/windows/win32/api//wingdi/nf-wingdi-exttextoutw#parameters">Read more on docs.microsoft.com</see>.</para>
/// </param>
/// <param name="lpDx">A pointer to an optional array of values that indicate the distance between origins of adjacent character cells. For example, lpDx[<i>i</i>] logical units separate the origins of character cell <i>i</i> and character cell <i>i</i> + 1.</param>
/// <returns>
/// <para>If the string is drawn, the return value is nonzero. However, if the ANSI version of <b>ExtTextOut</b> is called with ETO_GLYPH_INDEX, the function returns <b>TRUE</b> even though the function does nothing. If the function fails, the return value is zero.</para>
/// </returns>
/// <remarks>
/// <para><see href="https://docs.microsoft.com/windows/win32/api//wingdi/nf-wingdi-exttextoutw">Learn more about this API from docs.microsoft.com</see>.</para>
/// </remarks>
[DllImport("Gdi32", ExactSpelling = true, EntryPoint = "ExtTextOutW")]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
public static extern unsafe winmdroot.Foundation.BOOL ExtTextOut(winmdroot.Graphics.Gdi.HDC hdc, int x, int y, winmdroot.Graphics.Gdi.ETO_OPTIONS options, [Optional] winmdroot.Foundation.RECT* lprect, winmdroot.Foundation.PCWSTR lpString, uint c, [Optional] int* lpDx);
}
Expected behavior
uint c and int* lpDx should have separate parameters in generated ExtTextOut wrapper.
Repro steps
NativeMethods.txtcontent:
ExtTextOut
NativeMethods.jsoncontent:
{
"$schema": "https://aka.ms/CsWin32.schema.json",
"wideCharOnly": true,
"emitSingleFile": true,
"public": true
}
Context
- CsWin32 version: 0.1.635-beta
- Win32Metadata version (if explicitly set by project): implicit
- Target Framework:
net461;net472;netcoreapp3.1 LangVersion(if explicitly set by project):9.0
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue using the NativeMethods.txt and NativeMethods.json contents provided, then inspect the generated ExtTextOut wrapper against its native signature. The work is complete when the wrapper exposes uint c and int* lpDx as separate parameters and passes them correctly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100