Platform Invocation Services
Platform Invocation Services, mer känd som P/Invoke, är en funktion i implementationer av Common Language Infrastructure, som till exempel 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.
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 C- och C++-DLL:er kompilerade till maskinkod. Det är också användbart när man vill ha tillgång till Windows API, som helt består av DLL-filer med maskinkod, då det för många av funktionerna i Windows inte finns någon tillgängliga wrappers. Detta resulterar i att man måste skriva en wrapper till till exempel Win32 API.
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 __stdcall 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 __stdcall 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 __stdcall 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ällor
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