P/Invoke cheat sheet
I’m working a lot with p/invoke, and know how it’s hard to produce correct signature for unmanaged method. So, today I decided to publish basic cheat sheet for methods, parameters and attributes you should use in order to invoke unmanaged methods from managed code without a lot of problems. We start with data type translations. Here the table to understand it.
| Data type from unmanaged signature | Data type in managed signature |
| int | int
the same with all other simple types such as double, uint, etc or private objects |
| void* | IntPtr |
| int* | ref int
the same with all other simple types such as double, uint, etc or private objects |
| char** | ref IntPtr
later, you should get ascii string by using System.Runtime.InteropServices.Marshal.PtrToStringAnsi() method |
| wcar_t** | ref IntPtr
later, you should get ascii string by using System.Runtime.InteropServices.Marshal.PtrToStringUni() method |
| const int* | ref int |
| const char* | [System.Runtime.InteropServices.In()] [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string |
| … (variable argument) | [System.Runtime.InteropServices.In()] [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.AsAny)] object |
You can use either System.Runtime.InteropServices.In or System.Runtime.InteropServices.Out attribute to specify how arguments should be used.
Now we done with simple arguments, let’s see what can be done when argument is actually callback or delegate?
| Unmanaged definition | Managed definition |
| typedef void (*MyCallback)(int Arg) |
[System.Runtime.InteropServices.UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]delegate void MyCallback(int Arg) |
To call all those methods, we should know managed equivalents of unmanaged types. Here the table. The rule is simple – know how many bytes unmanaged type has and find managed type with the same number of bytes. Other words, you can marshal int into IntPtr too…
| Unmanaged type | Managed equivalent |
| bool | bool |
| char | sbyte (signed), byte (unsigned) |
| wchar_t | char |
| double | double |
| float | single |
| int, long (signed) | Int32 |
| int, long (unsigned) | UInt32 |
| __int64 (signed) | Int64 |
| __int64 | UInt64 |
| short (signed) | Int16 |
| short (unsigned) | UInt16 |
| void | void |
But not only types are problem in managed/unmanaged transitions. Also structures are aligned differently. For this purpose we can use StructLayout attribute. Even if unmanaged classes are sequential and you used correct managed data types, you can find you with problems in Pack. What “pack” is? Pack is actually slot size in bytes for members of your structure. It can be 0, 1, 2, 4, 8, 16, 32, 64, or 128 and depends on the platform and application setting.
Now you can see, that it is not very complicated to create managed signatures when you have header of unmanaged assemblies. So go ahead and ask, if I missed something.
That’s all by now. Have a nice day and be good people.
October 20th, 2008 · Comments (12)
12 Responses to “P/Invoke cheat sheet”
Leave a Reply
Discover other tags
My tools
- .NET Framework Detector
- Duplicate images finder
- Exchange Security Policy for Windows Mobile Devices Fix
- Gas Price Windows Vista SideBar gadget
- Israel Traffic Information Windows Vista SideBar gadget
- Localization fix for SAP ES Explorer for Visual Studio
- LocTester
- RTL and LTR in Windows Live Writer
- Silverlight controls library
- Snipping tool integration plugin for WLW
- USB FM receiver library
- Vista Battery Saver
- WebCam control for WPF
- Windows Live SkyDrive attachment for Windows Live Writer
- Wireless Migrator
- WPF Virtual Keyboard




January 1st, 2009 at 12:58 am
Recently I wrote a cheat sheet for pinvoking in .NET . Shortly after I got a question in comments about
January 1st, 2009 at 12:58 am
all,
i have a C++ function which I need to use from a C# project.
the prototype of the funtion is:
void complexFunction(char* arg1, …);
i don’t have any problem with the first argument but I’m having some issues with the variable arguments.
i used the "… (variable argument)" format specified here but i don’t know how to define the actual parameter. in the format it says "object" however i’m not able to pass any number of arguments, as the C++ function expects.
I tried to change from "object" to "params string[]" but the marshaler refused to accept this and i got an exception.
any idea?
thanks a lot!
Ofer
January 1st, 2009 at 12:58 am
pelister, it also, however dot net marshals variable pointer to var as reference to var. Actually every variable in managed code is passed by reference, rather then by value. So from this point of view there is no difference between int and int&
Tim, It’s absolutely aversome tool, however, it seemed, that it has it own problems too
January 1st, 2009 at 12:58 am
A lesser known tool, http://www.codeplex.com/clrinterop was released by the ms clr team somewhere around techEd US promises to take away a lot of the pain…
January 1st, 2009 at 12:58 am
Pingback from Dew Drop – October 21, 2008 | Alvin Ashcraft’s Morning Dew
January 1st, 2009 at 12:58 am
Hi, Clint
Working hard to prep to PDC
?
Yes, I know this site. This is great time saver, however the problem with it is that it contains unverified content and sometimes (most in less known methods) it just wrong
January 1st, 2009 at 12:58 am
as far as i know, the native equivalent of ref int should be int& and not int* am i wrong?
January 1st, 2009 at 12:58 am
This is awesome and extremely useful. Have you checked out http://www.pinvoke.net also? If it is a documented call, that site will give you the exact breakdown.
January 1st, 2009 at 12:58 am
You’ve been kicked (a good thing) – Trackback from DotNetKicks.com
January 7th, 2009 at 10:46 am
[...] P/Invoke it! But how to marshal unknown array? We should create wrapper object. Also there is very fun BitVector, used in this structure! What’s the problem? Pin it with some Math! [...]
February 17th, 2009 at 4:32 pm
But what it GC try to move the delegate?
October 24th, 2009 at 11:54 pm
it is bad, very very bad to use IntPtr. Since .net 2.0, it is better to adopt a user-defined subtype of SafeHandle. Search “writing reliable code” on MSDN.
BTW, i keep your webside in my favorites. So many wonderful posts of WPF. I was infoed that i am going to need WPF in just past friday.