HOME

TheInfoList



OR:

Platform Invocation Services, commonly referred to as P/Invoke, is a feature of Common Language Infrastructure implementations, like
Microsoft Microsoft Corporation is an American multinational technology corporation producing computer software, consumer electronics, personal computers, and related services headquartered at the Microsoft Redmond campus located in Redmond, Washin ...
's Common Language Runtime, that enables
managed code Managed code is computer program code that requires and will execute only under the management of a Common Language Infrastructure (CLI); Virtual Execution System (VES); virtual machine, e.g. .NET, CoreFX, or .NET Framework; Common Language Runt ...
to call
native code In computer programming, machine code is any low-level programming language, consisting of machine language instructions, which are used to control a computer's central processing unit (CPU). Each instruction causes the CPU to perform a ver ...
. Managed code, such as C# or VB.NET, provides native access to classes, methods, and types defined within the libraries that make up the .NET Framework. While the .NET Framework provides an extensive set of functionality, it may lack access to many lower level operating system libraries normally written in unmanaged code or third party libraries also written in unmanaged code. P/Invoke is the technique a programmer can use to access functions in these libraries. Calls to functions within these libraries occur by declaring the signature of the unmanaged function within managed code, which serves as the actual function that can be called like any other managed method. The declaration references the library's file path and defines the function parameters and return in managed types that are most likely to be implicitly marshaled to and from the unmanaged types by the common language run-time (CLR). When the unmanaged data types become too complex for a simple implicit conversion from and to managed types, the framework allows the user to define attributes on the function, return, and/or the parameters to explicitly refine how the data should be marshaled so as not to lead to exceptions in trying to do so implicitly. There are many abstractions of lower level programming concepts available to managed code programmers as compared to programming in unmanaged languages. As a result, a programmer with only managed code experience will need to brush up on programming concepts such as pointers, structures, and passing by reference to overcome some of the more basic, but common obstacles in using P/Invoke.


Architecture


Overview

Two variants of P/Invoke currently in use are:


Explicit

* Native code is imported via dynamic-linked libraries (DLLs) * Metadata embedded in the caller's assembly defines how the native code is to be called and data accessed (''usually requires attributed source specifiers to aid the compiler in generating marshal glue'') ** This definition is the "Explicit" part


Implicit

* By using
C++/CLI C++/CLI is a variant of the C++ programming language, modified for Common Language Infrastructure. It has been part of Visual Studio 2005 and later, and provides interoperability with other .NET languages such as C#. Microsoft created C++/CLI ...
, an application may simultaneously use the managed heap (by way of tracking pointers) and any native memory region, without the explicit declaration. (Implicit) * A primary benefit in this case being, if underlying native data structures change, so long as the naming is compatible, a
breaking change Backward compatibility (sometimes known as backwards compatibility) is a property of an operating system, product, or technology that allows for interoperability with an older legacy system, or with input designed for such a system, especially i ...
is avoided. ** i.e. Adding/removing/re-ordering structures in a native header will be transparently supported so long as the structure member names did not also change.


Details

When using P/Invoke, the
CLR CLR may refer to: * Calcium Lime Rust, a household cleaning-product * California Law Review, a publication by the UC Berkeley School of Law * Tube_bending, Centerline Radius, a term in the tubing industry used to describe the radius of a bend * Cen ...
handles DLL loading and conversion of the unmanaged previous types to
CTS Cts or CTS may refer to: Arts and entertainment Television * Chinese Television System, a Taiwanese broadcast television station, including: ** CTS Main Channel () ** CTS Education and Culture () ** CTS Recreation () ** CTS News and Info () ...
types (also referred to as ''parameter marshalling''). To perform this, the
CLR CLR may refer to: * Calcium Lime Rust, a household cleaning-product * California Law Review, a publication by the UC Berkeley School of Law * Tube_bending, Centerline Radius, a term in the tubing industry used to describe the radius of a bend * Cen ...
: * Locates the DLL containing the function. * Loads the DLL into memory. * Locates the address of the function in memory and pushes its arguments onto the stack, marshaling data as required. P/Invoke is useful for using standard (unmanaged) C or
C++ C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
DLLs. It can be used when a programmer needs to have access to the extensive
Windows API The Windows API, informally WinAPI, is Microsoft's core set of application programming interfaces (APIs) available in the Microsoft Windows operating systems. The name Windows API collectively refers to several different platform implementations th ...
, as many functions provided by the Windows libraries lack available wrappers. When a
Win32 API The Windows API, informally WinAPI, is Microsoft's core set of application programming interfaces (APIs) available in the Microsoft Windows operating systems. The name Windows API collectively refers to several different platform implementations th ...
is not exposed by the
.NET Framework The .NET Framework (pronounced as "''dot net"'') is a proprietary software framework developed by Microsoft that runs primarily on Microsoft Windows. It was the predominant implementation of the Common Language Infrastructure (CLI) until bein ...
the wrapper to this
API An application programming interface (API) is a way for two or more computer programs to communicate with each other. It is a type of software interface, offering a service to other pieces of software. A document or standard that describes how ...
must be written manually.


Pitfalls

Writing P/Invoke wrappers can be difficult and error prone. Using native DLLs means that the programmer can no longer benefit from
type safety In computer science, type safety and type soundness are the extent to which a programming language discourages or prevents type errors. Type safety is sometimes alternatively considered to be a property of facilities of a computer language; that i ...
and
garbage collection Waste collection is a part of the process of waste management. It is the transfer of solid waste from the point of use and disposal to the point of treatment or landfill. Waste collection also includes the curbside collection of recyclabl ...
as is usually provided in the .NET environment. When they are used improperly this may cause problems such as
segmentation fault In computing, a segmentation fault (often shortened to segfault) or access violation is a fault, or failure condition, raised by hardware with memory protection, notifying an operating system (OS) the software has attempted to access a restrict ...
s or
memory leak In computer science, a memory leak is a type of resource leak that occurs when a computer program incorrectly manages memory allocations in a way that memory which is no longer needed is not released. A memory leak may also happen when an object ...
s. Getting the exact signatures of the legacy functions for use in the .NET environment can be hard, which can result in such problems. For this purpose tools and websites exist to obtain such signatures, helping to prevent signature problems

Other pitfalls include: * Incorrect Data structure alignment, data alignment of user-defined
types Type may refer to: Science and technology Computing * Typing, producing text via a keyboard, typewriter, etc. * Data type In computer science and computer programming, a data type (or simply type) is a set of possible values and a set of allo ...
in the managed language: there are different ways data can be aligned depending on compilers or compiler directives in C and care must be taken to explicitly tell the
CLR CLR may refer to: * Calcium Lime Rust, a household cleaning-product * California Law Review, a publication by the UC Berkeley School of Law * Tube_bending, Centerline Radius, a term in the tubing industry used to describe the radius of a bend * Cen ...
how to align data for non-blittable types. A common example of this is when trying to define a data type in .NET to represent a
union Union commonly refers to: * Trade union, an organization of workers * Union (set theory), in mathematics, a fundamental operation on sets Union may also refer to: Arts and entertainment Music * Union (band), an American rock group ** ''Un ...
in C. Two different variables overlap in memory, and defining these two variables in a type in .NET would cause them to be in different locations in memory, so special attributes must be used to correct the issue. * Interference with the location of data by the managed language's garbage collector: if a reference is local to a method in .NET and is passed to a native function, when the managed method returns, the garbage collector may reclaim that reference. Care should be taken that the object reference is pinned, preventing it from being collected or moved by the garbage collector, which would result in an invalid access by the native module. When using C++/CLI, emitted CIL is free to interact with objects located on the managed heap and simultaneously any addressable native memory location. A managed heap resident object may be called, modified or constructed, using simple "object->field;" notation to assign values or specify method calls. Significant performance gains result from having eliminated any needless context switching, memory requirements are reduced (shorter stacks). This comes with new challenges: * Code is prone to Double Thunking if not specifically addressed * The ''Loader Lock issue'' These references specify solutions for each of these issue if they are encountered. A primary benefit is the elimination of the structure declaration, the order of field declaration and alignment issues are not present in the context of C++ Interop.


Examples


Basic examples

This first simple example shows how to get the version of a particular DLL: ''DllGetVersion'' function signature in the
Windows API The Windows API, informally WinAPI, is Microsoft's core set of application programming interfaces (APIs) available in the Microsoft Windows operating systems. The name Windows API collectively refers to several different platform implementations th ...
: HRESULT DllGetVersion ( DLLVERSIONINFO* pdvi ) P/Invoke C# code to invoke the ''DllGetVersion'' function: tructLayout(LayoutKind.Sequential)private struct DLLVERSIONINFO llImport("shell32.dll")static extern int DllGetVersion(ref DLLVERSIONINFO pdvi); The second example shows how to extract an icon in a file: ''ExtractIcon'' function signature in the Windows API: HICON ExtractIcon ( HINSTANCE hInst, LPCTSTR lpszExeFileName, UINT nIconIndex ); P/Invoke C# code to invoke the ''ExtractIcon'' function: llImport("shell32.dll")static extern IntPtr ExtractIcon( IntPtr hInst, arshalAs(UnmanagedType.LPStr)string lpszExeFileName, uint nIconIndex); This next complex example shows how to share an Event between two processes in the Windows platform: ''CreateEvent'' function signature: HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName ); P/Invoke C# code to invoke the ''CreateEvent'' function: llImport("kernel32.dll", SetLastError=true)static extern IntPtr CreateEvent( IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, arshalAs(UnmanagedType.LPStr)string lpName);


A more complex example

// native declaration typedef struct _PAIR PAIR, *PPAIR; // Compiled with /clr; use of #pragma managed/unmanaged can lead to double thunking; // avoid by using a stand-alone .cpp with .h includes. // This would be located in a .h file. template<> inline CLR_PAIR^ marshal_as (const PAIR&Src) ; CLR_PAIR^ mgd_pair1; CLR_PAIR^ mgd_pair2; PAIR native0,*native1=&native0; native0 = NativeCallGetRefToMemory(); // Using marshal_as. It makes sense for large or frequently used types. mgd_pair1 = marshal_as(*native1); // Direct field use mgd_pair2->Val1 = native0.Val1; mgd_pair2->val2 = native0.val2; return(mgd_pair1); // Return to C#


Tools

There are a number of tools which are designed to aid in the production of P/Invoke signatures. Writing a utility application that would import C++ header files and native DLL files and produce an interface assembly automatically turns out to be quite difficult. The main problem with producing such an importer/exporter for P/Invoke signatures is the ambiguity of some C++ function call parameter types. Brad Abrams has this to say on the subject
The P/Invoke Problem
The problem lies with C++ functions like the following: __declspec(dllexport) void MyFunction(char *params); What type should we use for the parameter params in our P/Invoke signature ? This could be either a C++ null terminated string, or could be a array or could be an output parameter. So should we use , , or ? Regardless of this issue, there are a few tools available to make the production of P/Invoke signatures simpler. One of the tools listed below
xInterop C++ .NET Bridge
has resolved this issue by implementing multiple overrides of the same C++ method in .NET world, developers can then pick the correct one to make the call.


PInvoke.net

PInvoke.net
is a wiki containing P/Invoke signatures for a large number of standard Windows APIs. It is owned b
Redgate Software
and has around 50000 hits per month. The signatures are manually produced by users of the wiki. They can be searched using

to Microsoft Visual Studio.


PInvoker

PInvoker
is an application which imports native DLLs and C++ .h files and exports fully formed and compiled interop DLLs. It overcomes the ambiguity problem by wrapping native pointer function parameters in PInvoker specific .NET interface classes. Instead of using standard .NET parameter types in P/Invoke method definitions (, , etc.) it uses these interface classes in the P/Invoke function calls. For instance, if we consider the above example code, PInvoker would produce a .NET function accepting a .NET interface class wrapping the native pointer. The construction of this class could be from a or from a array. The actual native memory structure for both is the same, but the respective interface class constructors for each type will populate the memory in different ways. The responsibility for deciding what .NET type needs to be passed into the function is therefore passed to the developer.


Microsoft Interop Assistant

Microsoft Interop Assistant
is a free tool available with binaries and source code available for download on
CodePlex CodePlex was a forge website by Microsoft. While it was active, it allowed shared development of open-source software. Its features included wiki pages, source control based on Mercurial, TFVC, Subversion or Git, discussion forums, issue tracki ...
. It is licensed under the Microsoft Limited Public License (Ms-LPL). It has two parts: * A converter which takes small sections of native C++ header file code containing and method definitions. It then produces C# P/Invoke code for you to copy and paste into your applications. * A searchable database of converted Windows API constant, method and struct definitions. Because this tool produces C# source code rather than a compiled dll the user is free to make any changes necessary to the code before use. So the ambiguity problem is solved by the application picking one particular .NET type to use in the P/Invoke method signature and if necessary the user can change this to the required type.


P/Invoke Wizard

Th
P/Invoke Wizard
uses a similar method to the Microsoft Interop Assistant in that it accepts native C++ .h file code and produces C# (or VB.NET) code for you to paste into your .NET application code. It also has options for which framework you wish to target: .NET Framework for the desktop or .NET Compact Framework for Windows Mobile smart devices (and Windows CE).


xInterop C++ .NET Bridge

xInterop C++ .NET Bridge
is a windows application to created C# wrapper for native C++ DLLs and C++ bridge to access .NET assemblies, it comes with a C#/.NET library which wraps the standard C++ classes, such as string, iostream, etc., C++ classes and objects can be accessed from .NET. This tool generates C# wrapper DLLs with source code from existing native C++ DLLs and the associated header files which are required by the tool to build a C# wrapper DLL. The P/Invoke signatures and data marshaling are generated by the application. The resulting C# wrapper has the similar interface of the C++ counterpart with the parameter type converted to the .NET code. This tool recognizes template classes which is not exported from the C++ DLL and instantiates the template class and export it in a supplement DLL and the corresponding C++ interface can be used in .NET.


See also

* Blittable types *
Java Native Interface In software design, the Java Native Interface (JNI) is a foreign function interface programming framework that enables Java code running in a Java virtual machine (JVM) to call and be called by native applications (programs specific to a hardwa ...
, the standard way for Java programs to access native code * Java Native Access, the Java equivalent of P/Invoke * Windows library files * J/Direct, the no-longer maintained equivalent API for Microsoft Java Virtual Machine


References


External links


A site devoted to P/Invoke

J/Invoke
Java access to Win32 API or Linux/Mac OS X shared libraries, similar to P/Invoke

Implicit P/Invoke with special focus on techniques for extending to the marshaling template
3 articles from Microsoft contrasting these methods
Using Explicit PInvoke, Implicit C++ Interop and "A Closer Look at Platform Invoke"
Microsoft Interop Assistant
Microsoft Interop Assistant main page.
P/Invoke Wizard
P/Invoke Wizard homepage.
PInvoker
PInvoker main page.
xInterop C++ .NET Bridge
xInterop C++ .NET Bridge main page {{Common Language Infrastructure .NET terminology Common Language Infrastructure