Platform Invocation Services
Från Rilpedia
Platform Invocation Services, mer känd som P/Invoke, är en funktion i implementationer av Common Language Infrastructure, som t.ex. Common Language Runtime, som tillåter hanterad kod att anropa maskinkod i DLL-filer. Maskinkoden refereras av metadata som beskriver funktionen som laddas ifrån DLL-filen.
Innehåll |
Användning
När P/Invoke används hanterar exekveringsmotorn (CLR) DLL-filerna och konverterar ohanterade typer till CTS-typer (så kallad parameter marshalling).
Följande sker under denna process:
- DLL-filen innehållande funktionen lokaliseras.
- Filen laddas in i minnet.
- Adressen till funktionen sparas i minnet och argumenten läggs på stacken. Därefter utförs operationerna som vanligt.
P/Invoke är mycket användbart när man vill använda gamla C och C++ DLL:er. Detta är också användbart när man vill ha tillgång till Windows API då det inte finns någon tillgängliga wrappers för många av funktionerna i Windows klassbibliotek. Detta resulterar till att man måste skriva en wrapper till t.ex. Win32 API.
Det kan vara väldigt svårt att skriva wrappers. Dessutom kan man inte längre ta del av den typsäkerhet och skräpinsamling som .NET Framework vanligtvis tillhandahåller. Om dessa används på ett felaktigt sätt kan det också orsaka segmenteringsfel och minnesläckor. Att hitta de rätta signaturerna för funktionerna kan vara svårt och kan orsaka sådana problem. Det finns en rad olika verktyg och webbsidor med hjälp.
Exempel
Det första exemplet visar hur du kan få reda vilken version en DLL har:
DllGetVersion funktion vars signatur finns i Windows API:
HRESULT DllGetVersion ( DLLVERSIONINFO* pdvi )
P/Invoke C#-kod som anropar funktionen DllGetVersion:
[DllImport("shell32.dll")] static extern int DllGetVersion(ref DLLVERSIONINFO pdvi);
Nästa exempel visar hur man extraherar en ikonfil.
Signaturen för funktionen ExtractIcon :
HICON ExtractIcon ( HINSTANCE hInst, LPCTSTR lpszExeFileName, UINT nIconIndex );
P/Invoke C#-kod som anropar funktionen ExtractIcon:
[DllImport("shell32.dll")] static extern IntPtr ExtractIcon( IntPtr hInst, [MarshalAs(UnmanagedType.LPStr)] string lpszExeFileName, uint nIconIndex);
Nästa exempel visar hur man skriver kod som delar ett Event mellan två program på Windows plattformen:
Signaturen för funktionen CreateEvent:
HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName );
P/Invoke C#-kod som anropar funktionen CreateEvent:
[DllImport("kernel32.dll", SetLastError=true)] static extern IntPtr CreateEvent( IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, [MarshalAs(UnmanagedType.LPStr)] string lpName);
Källa
Externa länkar
- Platform Invocation Services
- tutorial on P/Invoke
- a site devoted to P/Invoke
- J/Invoke Java access to Win32 API or Linux/Mac OS X shared libraries, similar to P/Invoke