Note that there are some explanatory texts on larger screens.

plurals
  1. POAccessing Win32 C/C++ struct members from C#
    primarykey
    data
    text
    <p>I am intercepting Win32 API calls a native dll or exe is doing from C# using some kind of hooking. In this particular case I am interested in DrawText() in user32.dll. It is declared like this in Win32 API:</p> <pre><code>INT WINAPI DrawTextW(HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags) </code></pre> <p>The LPRECT struct has the following signature (also in Win32 API):</p> <pre><code>typedef struct tagRECT { LONG left; LONG top; LONG right; LONG bottom; } RECT LPRECT; </code></pre> <p>LONG is a typedef for 32bit integers on 32bit systems (don't know about 64bit systems, it is irrelevant at this point because I am on 32bit Windows). To be able to access the members of this struct I declared it in my C# code...</p> <pre><code>[StructLayout(LayoutKind.Sequential, Pack = 1)] public struct RECT { public Int32 left; public Int32 top; public Int32 right; public Int32 bottom; } </code></pre> <p>... and wrote the signature of P/Invoke using this RECT struct:</p> <pre><code>[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)] static extern IntPtr DrawText(IntPtr HDC, String str, Int32 count, ref RECT rect, UInt32 flags, IntPtr dtp); </code></pre> <p>Since structs are value types in C# as opposed to being reference types like in C/C++, the ref modifier is necessary here.</p> <p>However when I use <code>rect.top rect.left</code> etc, they almost always return 0. I know for a fact that this is incorrect. But after googling countless hours and trying a lot of different things, I couldn't make this simple stuff work.</p> <p>Things I've tried:</p> <ul> <li>Using different primitives for RECT members (int, long, short, UInt32...). Actually it is kinda obvious that this is not a type problem because in any case I should see some garbled numbers, not 0.</li> <li>Removing ref modifier. This is also stupid (desperate times, desperate measures) because rect.left correctly returns the pointer to rect instead of its value.</li> <li>Tried <code>unsafe</code> code blocks. Didn't work but I may have made a mistake in the implementation (I don't remember what I've done). Besides this approach is generally reserved for tricky pointer situations in COM and Win32, it is overkill for my case anyway.</li> <li>Tried adding <code>[MarshallAs]</code> before the members of RECT. Made no difference.</li> <li>Played around with <code>Pack</code> values. No difference.</li> </ul> <p>I am fairly sure that I'm missing something very easy and straightforward but I have no idea what it is...</p> <p>Any help is appreciated. Thank you.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload