Tilgang Win32 C / C ++ struct medlemmer fra C #

stemmer
2

Jeg avskjære Win32 API kaller en innfødt dll eller exe gjør fra C # ved hjelp av noen form for hooking. I dette tilfellet er jeg interessert i DrawText () i user32.dll. Det er erklært som dette i Win32 API:

INT WINAPI DrawTextW(HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags)

Den LPRECT struct har følgende signatur (også i Win32 API):

typedef struct tagRECT { 
    LONG left;
    LONG top;
    LONG right;
    LONG bottom;
} RECT LPRECT;

LONG er et typedef for 32bit heltall på 32bit systemer (vet ikke om 64bit systemer, er det irrelevant på dette punktet fordi jeg er på 32bit Windows). For å kunne få tilgang til medlemmene av denne struct jeg erklært det i min C # -kode ...

[StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct RECT
    {
        public Int32 left;
        public Int32 top;
        public Int32 right;
        public Int32 bottom;
    }

... og skrev signaturen til P / Invoke bruker denne RECT struct:

[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);

Siden structs er verdityper i C # motsetning til å være referansetypene som i C / C ++, er dommeren modifier nødvendig her.

Men når jeg bruker rect.top rect.leftosv, de nesten alltid returnere 0. Jeg vet for et faktum at dette er feil. Men etter googling utallige timer og prøve en rekke forskjellige ting, kunne jeg ikke gjøre dette enkelt ting fungerer.

Ting jeg har prøvd:

  • Ved hjelp av forskjellige primitiver for RECT medlemmer (int, lange, korte, uint32 ...). Egentlig er det ganske åpenbart at dette ikke er en type problem fordi det i alle fall skal jeg se noen uleselige tall, ikke 0.
  • Fjerne ref modifier. Dette er også dumme (desperate tider, desperate tiltak) fordi rect.left returnerer pekeren riktig å rect i stedet for sin verdi.
  • Prøvde unsafekode blokker. Fungerte ikke, men jeg kan ha gjort en feil i implementeringen (Jeg husker ikke hva jeg har gjort). I tillegg til denne tilnærmingen er vanligvis reservert for vanskelige peker situasjoner i COM og Win32, er det overkill for mitt tilfelle uansett.
  • Prøvde å legge til [MarshallAs]før medlemmene av RECT. Gjorde ingen forskjell.
  • Spilt rundt med Packverdier. Ingen forskjell.

Jeg er ganske sikker på at jeg mangler noe veldig enkel og grei, men jeg har ingen anelse om hva det er ...

Alle hjelpe er verdsatt. Takk skal du ha.

Publisert på 14/10/2008 klokken 23:18
kilden bruker
På andre språk...                            


3 svar

Svarte 14/10/2008 kl. 23:40
kilden bruker

stemmer
2

Jeg legger merke til at du sier at du har prøvd [MarshallAs], men har du prøvd [MarshalAs(UnmanagedType.Struct)]?

Svarte 14/10/2008 kl. 23:43
kilden bruker

stemmer
1

En del av problemet er bruken av String der en Stringbuilder bør brukes.

Prøv denne signaturen (generert med PInvoke Interop Assistant )


[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct tagRECT {

    /// LONG->int
    public int left;

    /// LONG->int
    public int top;

    /// LONG->int
    public int right;

    /// LONG->int
    public int bottom;
}

public partial class NativeMethods {

    /// Return Type: int
    ///hdc: HDC->HDC__*
    ///lpchText: LPCWSTR->WCHAR*
    ///cchText: int
    ///lprc: LPRECT->tagRECT*
    ///format: UINT->unsigned int
    [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint="DrawTextW")]
public static extern  int DrawTextW([System.Runtime.InteropServices.InAttribute()] System.IntPtr hdc, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] System.Text.StringBuilder lpchText, int cchText, ref tagRECT lprc, uint format) ;

}
Svarte 15/10/2008 kl. 08:16
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more