|
The P/Invoke Wizard |
|
Last updated: May 15, 2004 By: Paul Yao The Paul Yao Company
|
|
click to download
click to order |
|
What is the P/Invoke Wizard?
|
|
I wrote the P/Invoke Wizard to save time for both myself and my co-author,
David Durant, while we were writing our .NET Compact Framework books. I wrote this tool
because I found that P/Invoke declarations were both tedious and error prone when
done by hand. Now with a few clicks of my mouse, I get complete and correct declarations
in a fraction of the time it previously took. My company started selling the P/Invoke
Wizard in 2002. Since finishing my books, I have been able to make some time to update
the tool - and now version 1.3 is available.
The P/Invoke Wizard is a tool that automates the process of writing
declarations in managed code for calling into unmanaged DLLs. With just a few mouse
clicks, the P/Invoke Wizard can opens a C or C++ include file and create thousands
of .NET-compatible P/Invoke declarations in a choice of C# or Visual Basic .NET.
The wizard can be set for compatibility with either the .NET Compact Framework or
the .NET Framework.
When we started selling the P/Invoke Wizard, we did not have a demo version; but a lot
of people were asking for what features are supported. We now offer a demo version that
you can download to see how well it works. There are two versions you can download: one
with the Microsoft MSI installer runtime (over 3MB), and one without (under 100K). The
demo version provides the full conversion for the registered, working version. The demo
version does not provide clipboard or file-save operations for converted declarations.
|
|
Background: What is P/Invoke?
|
|
P/Invoke - also known as "Platform Invoke" - lets managed code call
into unmanaged DLL functions. P/Invoke is supported in both the .NET Framework
and the .NET Compact Framework. There are differences between how P/Invoke works
in the two frameworks, and the P/Invoke Wizard lets you set an option for the framework
that you are targeting.
Sometimes it makes sense to port legacy native code to managed code. But
often, it makes sense to use existing native code DLLs that have already been written,
debugged, and deployed. P/Invoke helps bridge the gap between managed code and native
code, and the P/Invoke Wizard simplifies the task of creating managed code declarations
to access your native-code DLLs.
|
|
Can I avoid P/Invoke?
|
|
Can you avoid P/Invoke? For stand-alone, new code - perhaps. But if your
software relies on a native DLL for which you do not have the source code (perhaps
provided by a third-party). In that case, you have to use P/Invoke (or remove a feature
from the managed code version of your software -- something that users might not like).
Another situation when you need to use P/Invoke is when you want to access an operating
system feature not supported by the framework. On the desktop .NET Framework, you are
going to need to call P/Invoke for the following:
|
|
- ActiveX Controls
- Custom, Third-Party DLLs
- DirectX
- Drawing with 3D Graphics
- COM components
- Mail API (MAPI)
- Serial communications
- Structured Storage
- Telephony API (TAPI)
- Windows Hooks
|
|
While P/Invoke is helpful on the desktop, it is essential when building
Windows Mobile or Windows CE applications written for the .NET Compact Framework.
The Compact Framework brings to mobile and embedded devices some of the features
of the desktop .NET Framework. But many features from the desktop framework were
left out to adapt to the memory constraints of mobile and embedded devices. You get
an idea about the differences between the two frameworks when you consider that the
.NET Compact Framework is about 2 MB, a significant scaling back from the 25+ MB
of the desktop .NET Framework. Some of the areas where P/Invoke is critical for
Compact Framework programming includes the following:
|
|
- ActiveSync
- ActiveX Controls
- Carets
- CE Property databases
- Clipboard
- COM Components
- Common Dialog Boxes
- Cryptography API
- Custom controls
- Custom, Third-Party DLLs
- DirectX
- Fonts - enumerating available fonts; creating rotated fonts; using ClearType fonts
- File System enumeration - flash cards, directories, etc.
- Mail API (MAPI)
- Memory allocation of unmanaged memory
- Microsoft Message Queue (MSMQ)
- Pocket Outlook Object Model (POOM)
- Point-to-Point Message Queues
- Printing
- Real Time Threads
- Registry
- Running programs
- Serial Communications
- Shell functions
- Structured Storage
- Sounds
- Telephony API (TAPI)
- Stream interface drivers
- Windows Hooks
|
|
How Does The P/Invoke Wizard Work?
|
|
P/Invoke works by reading C/C++ include (.H) files. The P/Invoke processing
engine takes the various declarations and produces a compatible .NET version in your
choice of C# or Visual Basic .NET.
P/Invoke understands the following kinds of C/C++ declarations:
|
|
- #define statements for integer and string constants
- enum statements that define enumerated constant values
- typedef struct declarations that define the layout of structures
- typedef declarations for custom data types
- union statements
- function prototypes
|
|
The P/Invoke Wizard converts #define constants into the equivalent C#
or VB.NET declarations. It converts C/C++ data structure definitions and converts
them into the equivalent .NET data structures. It also reads C/C++ function prototypes
and generates the equivalent function.
|
|
Examples of P/Invoke Conversions
|
|
Here is an (admittedly) simple example of some C/C++ declarations that
were converted by the P/Invoke Wizard. Starting with this declaration:
|
|
|
// C/C++ input
#define PS_SOLID 0
#define PS_DASH 1
#define PS_NULL 5
typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT;
WINBASEAPI
DWORD
WINAPI
GetTempPathW(
DWORD nBufferLength,
LPWSTR lpBuffer);
|
|
|
|
With a click of the mouse, the above input gets converted into either C# or
Visual Basic.NET. The C# version to the above is shown here:
|
|
|
// [C#] output: managed code declarations
public const int PS_SOLID = 0;
public const int PS_DASH = 1;
public const int PS_NULL = 5;
[StructLayout(LayoutKind.Sequential,Pack=4)]
public struct RECT
{
public Int32 left;
public Int32 top;
public Int32 right;
public Int32 bottom;
};
[DllImport("kernel32.dll")]
public static extern Int32 GetTempPathW (UInt32 nBufferLength, String lpBuffer);
|
|
|
|
This code assumes that your C# code includes a reference to the System.Runtime.InteropServices namespace, with a statement like the following:
|
|
|
// [C#] required declaration
using System.Runtime.InteropServices;
|
|
|
|
For the above C/C++ declaration, the P/Invoke Wizard generates
the VB.NET declarations shown below:
|
|
|
' [VB] output: managed code declarations
public const PS_SOLID As Integer = 0
public const PS_DASH As Integer = 1
public const PS_NULL As Integer = 5
Public Structure RECT
Public left As Int32
Public top As Int32
Public right As Int32
Public bottom As Int32
End Structure
<DllImport("kernel32.dll")> _
Public Shared Function GetTempPathW ( _
ByVal nBufferLength As UInt32 _
, ByVal lpBuffer As String _
) As Int32
End Function
|
|
|
|
The above code assumes that your Visual Basic.NET code includes a reference to the System.Runtime.InteropServices namespace, with a statement like the following:
|
|
|
' [VB] required declaration
Imports System.Runtime.InteropServices
|
|
|
|
Supported P/Invoke Features
|
|
The previous example does not do justice to the available features that
the P/Invoke Wizard provides. We've used it extensively in writing production code for
both mobile and desktop managed code development, and keep adding new features as we
need them (and - increasingly - from our growing user base, as we hear about features that
are needed).
|
|
- Creates declarations in your choice of C# or Visual Basic .NET
- Supports selection of a target framework: .NET Framework for the desktop, and .NET Compact Framework for Windows Mobile smart devices (and Windows CE)
- Converts #define declarations to managed code constant declarations
- Optionally places like-named groups of contiguous #define constants into enumerations (based on proximity and similarity between constant names)
- Recognizes typedef declarations for application-specific data types
- Converts structure definitions into managed code structure declarations
- For arrays in structures, adds the MarshalAs attribute (desktop-only; not supported on mobile devices for CF 1.0)
- Convert function declarations into managed code function declarations using the appropriate DllImport attribute.
- For Visual Basic.NET, distinguishes between Sub (methods with no return value) and Function (methods with return values)
- Plus much more...
|
|
P/Invoke Wizard Benefits
|
|
The P/Invoke Wizard saves programmers time and frustration. What is your
time worth? If you have a large number of declarations to convert, this tool can eliminate
hours of tedious coding with the click of a mouse. The time saved is better spent working
on other, more interesting parts of your software projects.
What is it worth to you to eliminate some frustration from your work day - or from your life? Yes,
it's true that P/Invoke is very interesting to learn, and every managed code programmer is going to
want to create some declarations by hand. That helps you to really understand them. But when you
have a large number of declarations to handle, doing them by hand does not make sense; it is tedious
and error prone work.
The bottom line is that it makes more sense for software developers to spend
time on the creative and interesting challenges that their jobs demand of them.
|
|
P/Invoke Wizard Limitations
|
|
Version 1.3 of the P/Invoke Wizard relies on information found in include (*.H)
files. So if you do not have the include file, then P/Invoke cannot help you. It does
not, for example, use the binary DLL file for input. Nor does the P/Invoke Wizard use
a COM Type Library. In short, you need include (*.h) file declarations. Another limitation
is that this tool does not accept executable C++ statements -- function calls, loops, etc.
What it *does* provide is a shortcut when you have a lot of native code
declarations that you need to access from managed code. It saves your time. It saves
your frustration. Download the demo version today, using the link (below). When
you see much time you can save, register your copy using the other link (below).
|
|
click to download
click to order |