<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>jaredpar's WebLog : PInvoke</title><link>http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx</link><description>Tags: PInvoke</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Properly Incrementing an IntPtr</title><link>http://blogs.msdn.com/jaredpar/archive/2008/11/11/properly-incrementing-an-intptr.aspx</link><pubDate>Tue, 11 Nov 2008 16:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9042119</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/9042119.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=9042119</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=9042119</wfw:comment><description>&lt;p&gt;Just as native pointer types are moved around with pointer arithmetic in native code, it can also be useful to move IntPtr types around in managed code.&amp;#160; Say for instance there is an IntPtr available which points to a native array of Dog instances.&amp;#160; To access the values of that array individually requires pointer arithmetic of a fashion.&lt;/p&gt;  &lt;p&gt;For the most part this is a straight forward operation if the underlying native memory is understood.&amp;#160; Say there is an array of Dog instances with length 10 and the Dog structure has a size of 8.&amp;#160; The total amount of memory will be 80 bytes and with a valid dog instance being available at every 8 bytes.&amp;#160; So if the start address is 1000 then 1000,1008,1016 and so on will point to a valid instance.&lt;/p&gt;  &lt;p&gt;The native size of any data structure can be calculated via Marshal.SizeOf(tyepof(Dog)) [1].&amp;#160; With a pointer to the start of the array, the Nth Dog instance can be accessed with a pointer of address = (N*sizeof(Dog))+startAddress&lt;/p&gt;  &lt;p&gt;The address of a pointer can be accessed by 1 of 2 functions&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;.ToIn32() &lt;/li&gt;    &lt;li&gt;.ToInt64() &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Unless you are writing an application that will every only run on a 32 bit system, &lt;strong&gt;don’t use method #1&lt;/strong&gt; (even then still don’t).&amp;#160; Native pointer addresses vary in size depending on version of the OS a program is running on.&amp;#160; 64 bit systems have a much larger address size (long vs int).&amp;#160; Consequently calling .ToInt32 on a 64bit system will truncate the actual address to a valid that is no longer valid.&amp;#160; This will eventually lead to a random error PInvoke’ing a function that is difficult to track down.&lt;/p&gt;  &lt;p&gt;Instead use .ToInt64().&amp;#160; This method is safe on both 32 and 64 bit systems.&amp;#160; Additionally constructing an IntPtr instance with either value is safe.&amp;#160; The class knows what version of windows it’s executing on and will adjust the size in a safe way [2].&amp;#160; &lt;/p&gt;  &lt;p&gt;In many of my projects I define a class similar to the following to take care of this automatically.&amp;#160; &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public static class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IntPtrExtensions
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IntPtr &lt;/span&gt;Increment(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IntPtr &lt;/span&gt;ptr, &lt;span style="color: blue"&gt;int &lt;/span&gt;cbSize)
    {
        &lt;span style="color: blue"&gt;return new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt;(ptr.ToInt64() + cbSize);
    }

    &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IntPtr &lt;/span&gt;Increment&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IntPtr &lt;/span&gt;ptr)
    {
        &lt;span style="color: blue"&gt;return &lt;/span&gt;ptr.Increment(&lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;.SizeOf(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(T)));
    }

    &lt;span style="color: blue"&gt;public static &lt;/span&gt;T ElementAt&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IntPtr &lt;/span&gt;ptr, &lt;span style="color: blue"&gt;int &lt;/span&gt;index)
    {
        &lt;span style="color: blue"&gt;var &lt;/span&gt;offset = &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;.SizeOf(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(T))*index;
        &lt;span style="color: blue"&gt;var &lt;/span&gt;offsetPtr = ptr.Increment(offset);
        &lt;span style="color: blue"&gt;return &lt;/span&gt;(T)&lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;.PtrToStructure(offsetPtr, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(T));
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;[1] It’s highly advisable to not calculate this value yourself.&amp;#160; &lt;/p&gt;

&lt;p&gt;[2] See the post “&lt;a href="http://blogs.msdn.com/jaredpar/archive/2008/10/28/is-intptr-long-truncating.aspx"&gt;Is IntPtr(long) truncating?&lt;/a&gt;” for more details&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9042119" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Dereference a double IntPtr</title><link>http://blogs.msdn.com/jaredpar/archive/2008/11/05/dereference-a-double-intptr.aspx</link><pubDate>Wed, 05 Nov 2008 16:00:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9030818</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/9030818.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=9030818</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=9030818</wfw:comment><description>&lt;p&gt;A common PInvoke question is how to deal with a double pointer.&amp;#160; More specifically, how can one dereference an IntPtr to another pointer without using unsafe code?&amp;#160; &lt;/p&gt;  &lt;p&gt;Dereferencing a double pointer is done the same way a dereference to any other structure is done: &lt;a href="http://msdn.microsoft.com/en-us/library/4ca6d5z7.aspx"&gt;Marshal.PtrToStructure&lt;/a&gt;.&amp;#160; PtrToStructure is used to transform a native pointer, in the form of an IntPtr, into a managed version of the native data structure the native pointer points to.&lt;/p&gt;  &lt;p&gt;In the case of a double pointer, the native data structure the pointer points to is just another native pointer.&amp;#160; The managed equivalent is the IntPtr (or UIntPtr) class.&amp;#160; &lt;/p&gt;  &lt;p&gt;For Example, say we had the following native data signature&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;void &lt;/span&gt;GetDoublePointer(&lt;span style="color: blue"&gt;int&lt;/span&gt;** ppData)&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This function returns a pointer to a pointer that points to an int. (Pointer-&amp;gt;Pointer-&amp;gt;int).&amp;#160; We can then use the following C# code to access the final int value.&amp;#160; &lt;/p&gt;

&lt;pre class="code"&gt;[&lt;span style="color: #2b91af"&gt;DllImport&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;PInvokeSample.dll&amp;quot;&lt;/span&gt;)]
&lt;span style="color: blue"&gt;static extern void &lt;/span&gt;GetDoublePointer(&lt;span style="color: #2b91af"&gt;IntPtr &lt;/span&gt;doublePtr);

&lt;span style="color: blue"&gt;static void &lt;/span&gt;Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args)
{
    &lt;span style="color: blue"&gt;var &lt;/span&gt;ptr = &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;.AllocHGlobal(&lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;.SizeOf(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt;)));
    &lt;span style="color: blue"&gt;try
    &lt;/span&gt;{
        GetDoublePointer(ptr);
        &lt;span style="color: blue"&gt;var &lt;/span&gt;deref1 = (&lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;.PtrToStructure(ptr, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;IntPtr&lt;/span&gt;));
        &lt;span style="color: blue"&gt;var &lt;/span&gt;deref2 = (&lt;span style="color: blue"&gt;int&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;.PtrToStructure(deref1, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;int&lt;/span&gt;));
        &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(deref2);
    }
    &lt;span style="color: blue"&gt;finally
    &lt;/span&gt;{
        &lt;span style="color: #2b91af"&gt;Marshal&lt;/span&gt;.FreeHGlobal(ptr);
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9030818" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Is IntPtr(long) truncating?</title><link>http://blogs.msdn.com/jaredpar/archive/2008/10/28/is-intptr-long-truncating.aspx</link><pubDate>Tue, 28 Oct 2008 15:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9018607</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/9018607.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=9018607</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=9018607</wfw:comment><description>&lt;p&gt;The short answer is: No, not when it matters&lt;/p&gt;  &lt;p&gt;A colleague and I were discussing a particular scenario around IntPtr,PInvoke and 64 bit correctness.&amp;#160; Eventually our discussion lead us to the IntPtr constructor which takes a long.&amp;#160; To my surprise the code for the constructor is the following.&lt;/p&gt;  &lt;p&gt;public unsafe &lt;b&gt;&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.IntPtr/.ctor(Int64)"&gt;IntPtr&lt;/a&gt;&lt;/b&gt;(&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int64"&gt;long&lt;/a&gt; value) { this.&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.IntPtr/m_value:Void*"&gt;m_value&lt;/a&gt; = (&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Void"&gt;void&lt;/a&gt;*) ((&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt;) &lt;a&gt;value&lt;/a&gt;); }&lt;/p&gt;  &lt;p&gt;The problem is long value is arbitrarily truncated to an int.&amp;#160; This has the effect of essentially losing any address over the 4 GB range (in other words, no 64 bit addresses).&amp;#160; This much to big of a hole to actually be the real behavior so I decided to see if it was a bug in the disassembler.&amp;#160; I was using .Net Reflector so I switched to IL mode.&amp;#160; &lt;/p&gt;  &lt;pre&gt;    L_0000: ldarg.0 
    L_0001: ldarg.1 
    L_0002: conv.ovf.i4 
    L_0003: conv.i 
    L_0004: stfld void* System.IntPtr::m_value
    L_0009: ret &lt;/pre&gt;

&lt;p&gt;This confirmed it is indeed truncating the value (and doing an overflow check to boot). But wait, mscorlib.dll is a processor specific DLL so perhaps this is just a 32 bit OS thing.&amp;#160; I switched over to a 64 bit machine, fired up Reflctor and found to my dismay that it had the exact same code.&amp;#160; &lt;/p&gt;

&lt;p&gt;After a few minutes I thought to open up task manager and to my surprise reflector was running in a WoW64 bit process.&amp;#160; This meant it was still loading up the 32 bit version of mscorlib.dll.&amp;#160; Next I fired up ildasm, loaded up a 64 bit mscorlib and confirmed that the code will not truncate on 64 bit machines. &lt;/p&gt;

&lt;pre&gt;  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  conv.u
  IL_0003:  stfld      void* System.IntPtr::m_value
  IL_0008:  ret&lt;/pre&gt;

&lt;p&gt;The conv.u code is a conversion to unsigned native platform int. On a 64 bit machine this will be an unsigned 8 byte number(see &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.conv_u.aspx"&gt;OpCodes.Conv_U&lt;/a&gt; for more details).&amp;#160; &lt;/p&gt;

&lt;p&gt;So what does this mean for the developer.&amp;#160; Essentially IntPtr(long) will do the right thing independently of the platform a developer is using.&amp;#160; On a 32 bit platform it will (correctly) throw exceptions if a non-4GB address is passed in.&amp;#160; In 64 bit land it will essentially do nothing and rely on the programmer to give correct addresses.&amp;#160; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9018607" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/DotNet/default.aspx">DotNet</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Wow64/default.aspx">Wow64</category></item><item><title>PInvoke and bool (or should I say BOOL)?</title><link>http://blogs.msdn.com/jaredpar/archive/2008/10/14/pinvoke-and-bool-or-should-i-say-bool.aspx</link><pubDate>Tue, 14 Oct 2008 15:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8997315</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8997315.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8997315</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8997315</wfw:comment><description>&lt;p&gt;Boolean value types are a constant source of problems for people attempting to generate PInvoke signatures.&amp;nbsp; It's yet another case of managed and native types differing on size.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;There are two common boolean types in native code: bool and BOOL.&amp;nbsp; As with most PInvoke issue the main issue is to understand the size&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;bool: 1 byte &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;bool SomeOperation();&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;BOOL: 4 bytes&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;BOOL SomeOtherOperation();&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;Fortunately there is only one managed boolean type.&amp;nbsp; Unfortunately though, it has 2 sizes that must be considered.&amp;nbsp; In managed code a bool is a single byte.&amp;nbsp; Yet the default marshalling for a bool will expand it to 4 bytes.&amp;nbsp; So even though bool is 1 byte in managed code, it is by default compatible with the 4 byte native version BOOL.&amp;nbsp; &lt;br&gt;&lt;/p&gt;  &lt;p&gt;Translating a PInvoke signature for a native 1 byte bool is simple enough though.&amp;nbsp; The &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.unmanagedtype%28VS.80%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.unmanagedtype(VS.80).aspx"&gt;UnmanagedType&lt;/a&gt;.I1 value allows for this scenario.&amp;nbsp; It tells the CLR that while the managed code has a boolean value the
corresponding native item is the 1 byte version of bool.&amp;nbsp; The CLR will then make
the necessary size adjustments.&amp;nbsp; When converting native -&amp;gt; managed
it will consider a non-zero value true and 0 to be false.&amp;nbsp;&lt;/p&gt;  &lt;p&gt;Native:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;bool SomeOperation();&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Managed:&lt;/p&gt;  &lt;pre class="code"&gt;[&lt;span style="color: blue;"&gt;return&lt;/span&gt;: &lt;span style="color: rgb(43, 145, 175);"&gt;MarshalAs&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;UnmanagedType&lt;/span&gt;.I1)]&lt;br&gt;&lt;span style="color: blue;"&gt;public static extern bool &lt;/span&gt;SomeOperation();&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;



&lt;p&gt;BOOL's can be usefully marshalled in two different ways.&amp;nbsp; The first is simply as a int (signed or unsigned).&amp;nbsp; This works because int matches the size requirement of a BOOL and the sign is not really important as true or false is simply 0 or not 0.&amp;nbsp; &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;public static extern int &lt;/span&gt;SomeOtherOperation();&lt;/pre&gt;

&lt;p&gt;This is certainly sub-optimal since we're now returning a non-boolean type for what is intended to be a boolean operation but some people choose to Marshal it this way.&amp;nbsp; &lt;br&gt;&lt;/p&gt;

&lt;p&gt;Marshaling a native BOOL to a managed bool works without any annotations.&amp;nbsp; However it is preferred that you include the annotations to make it much clearer what the native data type is.&amp;nbsp; The &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.unmanagedtype%28VS.80%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.unmanagedtype(VS.80).aspx"&gt;UnmanagedType&lt;/a&gt; enumeration contains a Bool value for just this purpose.&amp;nbsp; This can be applied to any managed bool return or parameter.&amp;nbsp; &lt;br&gt;&lt;/p&gt;

&lt;pre class="code"&gt;[&lt;span style="color: blue;"&gt;return&lt;/span&gt;: &lt;span style="color: rgb(43, 145, 175);"&gt;MarshalAs&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;UnmanagedType&lt;/span&gt;.Bool)]&lt;br&gt;&lt;span style="color: blue;"&gt;public static extern bool &lt;/span&gt;SomeOtherOperation();&lt;/pre&gt;

&lt;p&gt;And presto, we have maintained the boolean semantics of the operation.&amp;nbsp; &lt;/p&gt;

&lt;p&gt;Hint: If you are using the &lt;a href="http://www.codeplex.com/clrinterop" mce_href="http://www.codeplex.com/clrinterop"&gt;PInvoke Interop Assistant&lt;/a&gt;, it will automatically do these conversions for you.&amp;nbsp; &lt;/p&gt;&lt;p&gt;&lt;b&gt;Edit&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Fixed a mixup on the default native size of bool.&amp;nbsp; Thanks to &lt;span class="rwRRO"&gt;&lt;/span&gt;Jachym Kouba for pointing out the mistake&lt;br&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8997315" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>When is a LONG not a long?</title><link>http://blogs.msdn.com/jaredpar/archive/2008/10/02/when-is-a-long-not-a-long.aspx</link><pubDate>Thu, 02 Oct 2008 15:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8969419</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8969419.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8969419</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8969419</wfw:comment><description>&lt;P&gt;Answer: When PInvoke is involved.&lt;/P&gt;
&lt;P&gt;I ran across a common error today on &lt;A href="http://stackoverflow.com/questions/148856/using-pinvoke-correctly#150019" mce_href="http://stackoverflow.com/questions/148856/using-pinvoke-correctly#150019"&gt;stackoverflow&lt;/A&gt; regarding P/Invoke that is worth blogging about.&amp;nbsp; The question regarded the translation of a native API with a parameter of type LONG.&amp;nbsp; The user mistakenly used the .Net long type as the parameter.&amp;nbsp; The error is that a C++ LONG is not the same as a .Net long.&lt;/P&gt;
&lt;P&gt;When talking about types and PInvoke it's easier to discuss byte size and signed-ness than type names.&amp;nbsp; Otherwise confusion around long and short crop up.&amp;nbsp; Really there are four integer byte sizes each of which can be signed or unsigned: 1,2,4 and 8&lt;/P&gt;
&lt;P&gt;The problem the user encountered is the C++ long is 4 byte signed and .Net long is 8 byte signed.&amp;nbsp; PInvoke requires the parameters to have the same size.&amp;nbsp; Below is a quick table of the various types in C++ and .Net.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;1 byte&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;C++ - char, __int8, BYTE, BOOLEAN&lt;/LI&gt;
&lt;LI&gt;.Net - byte&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;2 byte&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;C++ - wchar, __int16, short, WORD&lt;/LI&gt;
&lt;LI&gt;.Net - char, short&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;4 byte &lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;C++ - int, LONG, long, __int32, DWORD&lt;/LI&gt;
&lt;LI&gt;.Net - int&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;8 byte&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;C++ - __int64, LONGLONG, DWORDLONG, LARGE_INTEGER&lt;/LI&gt;
&lt;LI&gt;.Net - long&lt;/LI&gt;&lt;/UL&gt;&lt;/UL&gt;
&lt;P&gt;Based on this table when translating a C++ LONG, you should use a .Net int. &lt;/P&gt;
&lt;P&gt;Edit1: Moved C++ short to 2 byte, added several other C++ types. (thanks Raymond)&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8969419" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category></item><item><title>PInvoke Interop Assistant on Channel 9</title><link>http://blogs.msdn.com/jaredpar/archive/2008/09/11/pinvoke-interop-assistant-on-channel-9.aspx</link><pubDate>Thu, 11 Sep 2008 15:00:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8936056</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8936056.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8936056</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8936056</wfw:comment><description>&lt;p&gt;Beth Massi dropped by my office a couple of months ago and we did a channel 9 video on the &lt;a href="http://www.codeplex.com/clrinterop"&gt;PInvoke Interop Assistant&lt;/a&gt;.&amp;#160; Mainly an overview of the product and a bit of a tutorial.&amp;#160; Check out the video here.&lt;/p&gt;  &lt;p&gt;&lt;a title="http://channel9.msdn.com/posts/funkyonex/The-P-Invoke-Interop-Assistant/" href="http://channel9.msdn.com/posts/funkyonex/The-P-Invoke-Interop-Assistant/"&gt;http://channel9.msdn.com/posts/funkyonex/The-P-Invoke-Interop-Assistant/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8936056" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Misc/default.aspx">Misc</category></item><item><title>PInvoke Interop Assistant now on CodePlex</title><link>http://blogs.msdn.com/jaredpar/archive/2008/06/17/pinvoke-interop-assistant-now-on-codeplex.aspx</link><pubDate>Tue, 17 Jun 2008 15:00:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8608265</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8608265.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8608265</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8608265</wfw:comment><description>&lt;p&gt;I'm happy to announce that the &lt;a href="http://blogs.msdn.com/jaredpar/archive/2008/03/14/making-pinvoke-easy.aspx."&gt;PInvoke Interop Assistant&lt;/a&gt; tool is now available on CodePlex.&amp;#160; This includes the binaries, source code and the dev authored unit tests.&amp;#160; &lt;/p&gt;  &lt;p&gt;It is hosted on the more general CLR Interop Tools page.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.codeplex.com/clrinterop" href="http://www.codeplex.com/clrinterop"&gt;http://www.codeplex.com/clrinterop&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I will be actively maintaining this tool in the future and (hopefully) adding more features.&amp;#160; There were several features we cut just before release due to QA costing that I would like to add back (including VS integration, wrapper functions).&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;Please post any suggestions you have for the tool on the site and we will definitely consider them. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8608265" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category></item><item><title>Making PInvoke Easy</title><link>http://blogs.msdn.com/jaredpar/archive/2008/03/14/making-pinvoke-easy.aspx</link><pubDate>Fri, 14 Mar 2008 19:58:39 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8206460</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8206460.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8206460</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8206460</wfw:comment><description>&lt;p&gt;I very excited to announce we recently released a tool I've been working on to MSDN that will greatly help with using PInvoke in managed code.&amp;nbsp; The tool is called the "PInvoke Interop Assistant" and is included as part of a MSDN article on marshalling data for PInvoke and Reverse PInvoke scenarios.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Here is a link to the article and tool&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Article: &lt;a title="http://msdn2.microsoft.com/en-us/magazine/cc164193.aspx" href="http://msdn2.microsoft.com/en-us/magazine/cc164193.aspx"&gt;http://msdn2.microsoft.com/en-us/magazine/cc164193.aspx&lt;/a&gt;  &lt;li&gt;Tool: &lt;a title="CLRInsideOut2008_01.exe" href="http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/CLRInsideOut2008_01.exe"&gt;CLRInsideOut2008_01.exe&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The motivation behind this tool is writing PInvoke is a hard and often tedious task. There are many rules you must obey and many exceptions that must be taken into account.&amp;nbsp; Anything beyond simple data structures gets very involved and subtle semantics of C can greatly change the needed signature.&amp;nbsp; Incorrect translations often result in obscure exceptions or crashes.&lt;/p&gt; &lt;p&gt;In short, it's not any fun. &lt;/p&gt; &lt;p&gt;The tool works in several different ways to make PInvoke generation an easier process.&amp;nbsp; The goal is to make generating managed code for structs, unions, enums, constants, functions, typedefs , etc ... as easy as possible. The resulting code can be generated in both VB and C#. &lt;/p&gt; &lt;p&gt;The GUI version of the tool operates in 3 modes.&amp;nbsp;&amp;nbsp; &lt;/p&gt; &lt;ol&gt; &lt;li&gt;SigImp Search: Search for a commonly used function and translate it into managed code.  &lt;li&gt;SigImp Translate Snippet: Directly translate C code into managed PInvoke signatures.  &lt;li&gt;SigExp: Convert managed binaries into C++ Reverse PInvoke scenarios&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;The first two are the parts I worked on and represent the PInvoke scenarios.&amp;nbsp; The third part was written by Ladi Prosek and will be covered in a different article. We chose the names SigImp and SigExp to mirror the tblimp/tlbexp tool base since they have similar functions.&lt;/p&gt; &lt;h3&gt;Directly translating C code into PInvoke Signatures&lt;/h3&gt; &lt;p&gt;Most adventures in PInvoke start with a developer having a small set of C code they would like to use from a managed binary.&amp;nbsp; Typically it's one or two functions with several supporting C structs.&amp;nbsp; Before, all of this would be hand translated into managed code from scratch.&amp;nbsp; With this tool all you must do is paste the code into the tool and it will generate the interop signature for you.&amp;nbsp; &lt;/p&gt; &lt;p&gt;For instance assume you wanted to translate the following C code into VB.&amp;nbsp; &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;struct&lt;/span&gt; S1
{
  &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; a;
  &lt;span style="color: rgb(0,0,255)"&gt;char&lt;/span&gt;[10] b;
};

&lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; CalculateData(S1* p);&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Start up the tool and switch to the "SigImp Translate Snippet" tab.&amp;nbsp; Then paste the code in and then hit the Generate button.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jaredpar/WindowsLiveWriter/MakingPInvokeEasy_E069/PInvoke1_4.png" target="_blank"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="157" alt="PInvoke1" src="http://blogs.msdn.com/blogfiles/jaredpar/WindowsLiveWriter/MakingPInvokeEasy_E069/PInvoke1_thumb_1.png" width="244" border="0"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You can also set click the "Auto Generate" box and watch the code update as you type.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;This translation is not limited to built-in C types.&amp;nbsp; It will also resolve most commonly used windows types such as HANDLE, DWORD all the way up to complex structs such as &lt;a href="http://msdn2.microsoft.com/en-us/library/aa365740(VS.85).aspx"&gt;WIN32_FIND_DATA&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Searching for a commonly used function&lt;/h3&gt;
&lt;p&gt;Often developers want to use C functions familiar to them in managed code.&amp;nbsp; This can be a tedious task as well because if the signature is not already available you are back to coding from scratch.&amp;nbsp; Even adding a constant value can be tricky if you don't know which header file to look in.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The tool also provides a database of many commonly used functions, structs, constants, etc ... It is essentially anything that is included from windows.h.&amp;nbsp; Switch to the SigImp search tab, type the name of what you are looking for and hit generate.&amp;nbsp; For example if I want to see the value for WM_PAINT just type it in.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jaredpar/WindowsLiveWriter/MakingPInvokeEasy_E069/Pinvoke2_2.png" target="_blank"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="157" alt="Pinvoke2" src="http://blogs.msdn.com/blogfiles/jaredpar/WindowsLiveWriter/MakingPInvokeEasy_E069/Pinvoke2_thumb.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;In addition this part of the tool will also do dependency calculation.&amp;nbsp; For instance if choose a method which has a parameter that is a C structure it will automatically generate the structure with the function.&amp;nbsp; For instance if you choose the function &lt;a href="http://msdn2.microsoft.com/en-us/library/aa364418.aspx"&gt;FindFirstFile&lt;/a&gt; it will determine that the function depends on the WIN32_FIND_DATA structure.&amp;nbsp; Furthermore it will notice that WIN32_FIND_DATA depends on FILETIME and generate both in addition to the method.&lt;/p&gt;&lt;pre class="code"&gt;&amp;lt;System.Runtime.InteropServices.StructLayoutAttribute( _
    System.Runtime.InteropServices.LayoutKind.Sequential, _
    CharSet:=System.Runtime.InteropServices.CharSet.[Unicode])&amp;gt; _
&lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Structure&lt;/span&gt; WIN32_FIND_DATAW
    &lt;span style="color: rgb(0,128,0)"&gt;'''DWORD-&amp;gt;unsigned int
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; dwFileAttributes &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;UInteger
&lt;/span&gt;    &lt;span style="color: rgb(0,128,0)"&gt;'''FILETIME-&amp;gt;_FILETIME
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; ftCreationTime &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; FILETIME
    &lt;span style="color: rgb(0,128,0)"&gt;'''FILETIME-&amp;gt;_FILETIME
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; ftLastAccessTime &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; FILETIME
    &lt;span style="color: rgb(0,128,0)"&gt;'''FILETIME-&amp;gt;_FILETIME
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; ftLastWriteTime &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; FILETIME
    &lt;span style="color: rgb(0,128,0)"&gt;'''DWORD-&amp;gt;unsigned int
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; nFileSizeHigh &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;UInteger
&lt;/span&gt;    &lt;span style="color: rgb(0,128,0)"&gt;'''DWORD-&amp;gt;unsigned int
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; nFileSizeLow &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;UInteger
&lt;/span&gt;    &lt;span style="color: rgb(0,128,0)"&gt;'''DWORD-&amp;gt;unsigned int
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; dwReserved0 &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;UInteger
&lt;/span&gt;    &lt;span style="color: rgb(0,128,0)"&gt;'''DWORD-&amp;gt;unsigned int
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; dwReserved1 &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;UInteger
&lt;/span&gt;    &lt;span style="color: rgb(0,128,0)"&gt;'''WCHAR[260]
&lt;/span&gt;    &amp;lt;System.Runtime.InteropServices.MarshalAsAttribute( _
        System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=260)&amp;gt; _
    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; cFileName &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;String
&lt;/span&gt;    &lt;span style="color: rgb(0,128,0)"&gt;'''WCHAR[14]
&lt;/span&gt;    &amp;lt;System.Runtime.InteropServices.MarshalAsAttribute( _
        System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=14)&amp;gt; _
    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; cAlternateFileName &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;String
End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Structure

&lt;/span&gt;&amp;lt;System.Runtime.InteropServices.StructLayoutAttribute( _
    System.Runtime.InteropServices.LayoutKind.Sequential)&amp;gt; _
&lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Structure&lt;/span&gt; FILETIME
    &lt;span style="color: rgb(0,128,0)"&gt;'''DWORD-&amp;gt;unsigned int
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; dwLowDateTime &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;UInteger
&lt;/span&gt;    &lt;span style="color: rgb(0,128,0)"&gt;'''DWORD-&amp;gt;unsigned int
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; dwHighDateTime &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;UInteger
End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Structure

Partial&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Class&lt;/span&gt; NativeMethods
    &lt;span style="color: rgb(0,128,0)"&gt;'''Return Type: HANDLE-&amp;gt;void*
&lt;/span&gt;    &lt;span style="color: rgb(0,128,0)"&gt;'''lpFileName: LPCWSTR-&amp;gt;WCHAR*
&lt;/span&gt;    &lt;span style="color: rgb(0,128,0)"&gt;'''lpFindFileData: LPWIN32_FIND_DATAW-&amp;gt;_WIN32_FIND_DATAW*
&lt;/span&gt;    &amp;lt;System.Runtime.InteropServices.DllImportAttribute(&lt;span style="color: rgb(163,21,21)"&gt;"kernel32.dll"&lt;/span&gt;, EntryPoint:=&lt;span style="color: rgb(163,21,21)"&gt;"FindFirstFileW"&lt;/span&gt;)&amp;gt; _
    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Shared&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; FindFirstFileW( _
        &amp;lt;System.Runtime.InteropServices.InAttribute(), _
            System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)&amp;gt; _
            &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; lpFileName &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;String&lt;/span&gt;, _
        &amp;lt;System.Runtime.InteropServices.OutAttribute()&amp;gt; _
        &lt;span style="color: rgb(0,0,255)"&gt;ByRef&lt;/span&gt; lpFindFileData &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; WIN32_FIND_DATAW) &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; System.IntPtr
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function
End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Class&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;h3&gt;Translating Large Code bases&lt;/h3&gt;
&lt;p&gt;The snippet translator works well for small snippets of code.&amp;nbsp; If you are trying to translate a much larger code base, say several interdependent header files the small snippet dialog won't work well.&amp;nbsp; To work with larger code bases you should use the command line version of the tool;&amp;nbsp; sigimp.exe.&amp;nbsp; It is designed to process several header files and produce a mass output.&amp;nbsp; &lt;/p&gt;
&lt;h3&gt;Wrapping Up&lt;/h3&gt;
&lt;p&gt;This tool started out as a pet project of mine some time ago.&amp;nbsp; I'm extremely excited that customers are now going to be able to take advantage of it and I greatly look forward to any feedback you have.&amp;nbsp; I will post a couple more articles in the future detailing how this tool works under the hood.&amp;nbsp; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8206460" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category></item><item><title>Follow up: PInvoke with 32 and 64 bit</title><link>http://blogs.msdn.com/jaredpar/archive/2006/04/13/follow-up-pinvoke-with-32-and-64-bit.aspx</link><pubDate>Fri, 14 Apr 2006 00:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:576081</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/576081.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=576081</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=576081</wfw:comment><description>&lt;P&gt;Recently after I made my original post titled “PInvoke with 32 and 64 bit”, a developer emailed me.&amp;nbsp; They pointed out that there is an internal structure that dynamically resizes based on the architecture; IntPtr.&amp;nbsp; IntPtr will be size of the native chip pointer value.&amp;nbsp; So for values like size_t that map to the pointer size, you can use the Address field of IntPtr.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;This approach has some small down sides. &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The type you are marshaling must have the same size as IntPtr for all of the architecture's you run on 
&lt;LI&gt;If you expose an interop API that uses IntPtr in this manner, you have to find a good way to inform your users that they really need to pass the value in the address of the IntPtr &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;A way to get around #2 is to define your own type (like I did with SizeT) and just wrap an IntPtr. If you have no other fields in your type it will Marshall like an IntPtr. You can provide friendly properties that assign values into the IntPtr's Address property.&lt;/P&gt;
&lt;P&gt;If you have a type who's size does not change in the same way as IntPtr then you'll probably have to go the custom marshal route&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=576081" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category></item><item><title>Marshaling Nested Data Structures Part 4</title><link>http://blogs.msdn.com/jaredpar/archive/2005/07/18/marshaling-nested-data-structures-part-4.aspx</link><pubDate>Mon, 18 Jul 2005 16:51:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:439457</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/439457.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=439457</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=439457</wfw:comment><description>&lt;P&gt;This is part&amp;nbsp;4 of a series.&amp;nbsp; You can find &lt;A href="http://blogs.msdn.com/jaredpar/archive/2005/07/11/437584.aspx" mce_href="http://blogs.msdn.com/jaredpar/archive/2005/07/11/437584.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;part one here&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt;.&amp;nbsp; Please refer to that article for all of the Native definitions of the structures that I use here.&lt;/P&gt;
&lt;P&gt;In the previous article we were left with a solution where using the code was very clean but the actualy implementation had extra allocation and perf overhead.&amp;nbsp; We'll conquer both of those in this installment by implementing a custom marshaler for our Course object.&amp;nbsp; This is accomplished by implementing ICustomMarshaler and call the class CourseMarshaler.&amp;nbsp; &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemruntimeinteropservicesicustommarshalermemberstopic.asp" mce_href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemruntimeinteropservicesicustommarshalermemberstopic.asp"&gt;(ICustomMarshaler docs)&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Custom marshaling is exactly like it sounds.&amp;nbsp; The marshaler itself does practically nothing.&amp;nbsp; Your code must transform the managed data structure into a native format and vice versa.&amp;nbsp; It can be tedious at times but this method can be used to marshal even the most complex of structures.&amp;nbsp; There are 6 methods you must implement.&amp;nbsp; Lets go over each of them.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;CleanupData() - Use this method to dispose of anything on your managed object when it's no longer needed.&amp;nbsp; Typically there is nothing to do here and this method remains blank as it does in our case.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;CleanupNativeData()&amp;nbsp;- Use this method to free up any data associated with the Native pointer after the runtime is finished using it.&amp;nbsp; In our case, we have to allocate memory to Marshal the data structure into, so we need to free up this pointer.&amp;nbsp; &lt;/P&gt;&lt;PRE&gt;public void CleanUpNativeData(IntPtr pNativeData)
{
    Marshal.FreeCoTaskMem(pNativeData);
}&lt;/PRE&gt;
&lt;P&gt;GetNativeDataSize() - Returns the size of the unmanaged data structure.&amp;nbsp; As previously discussed, this size is 268. &lt;/P&gt;
&lt;P&gt;MarshalManagedToNative() - Takes in an object and returns a pointer to the memory that contains the Native structure in memory.&amp;nbsp; To complete this we need to allocate a block of memory, and then marshal each of the fields in order into that memory block and return the pointer to the front of the block.&amp;nbsp; The pointer we allocate will be freed later when the runtime passes it into CleanupNativeData().&amp;nbsp; Some error checking was removed for the sake of brevity.&amp;nbsp; &lt;/P&gt;&lt;PRE&gt;public IntPtr MarshalManagedToNative(object managedObj)
{
    Course course = (Course)managedObj;
&lt;/PRE&gt;&lt;PRE&gt;    IntPtr ptr = Marshal.AllocCoTaskMem(this.GetNativeDataSize());
    if (IntPtr.Zero == ptr)
    {
        throw new Exception("Could not allocate memory");
    }
&lt;/PRE&gt;&lt;PRE&gt;    // Write the Int values in order into memory
    Marshal.WriteInt32(ptr, 0, course.Id);
    Marshal.WriteInt32(ptr, Marshal.SizeOf(typeof(Int32)), course.Count);
            
    // Now we need to Marshal each of the Student elements into the "array".  This 
    // starts immediately after the Ints
    IntPtr cur = new IntPtr(ptr.ToInt32() + (2 * Marshal.SizeOf(typeof(Int32))));
    for (int i = 0; i &amp;lt; course.Count; i++)
    {
         Student student = course.Students[i];
         Marshal.StructureToPtr(student, cur, false);
         cur = new IntPtr(cur.ToInt32() + Marshal.SizeOf(typeof(Student)));
    }
    return ptr;
}&lt;/PRE&gt;
&lt;P&gt;MarshalManagedToNative() - Marshal the Native Struct into a managed version.&amp;nbsp; This is almost identical to the sample that we did in part 3.&amp;nbsp; Code reposted below.&amp;nbsp; &lt;/P&gt;&lt;PRE&gt;public object MarshalNativeToManaged(IntPtr ptr)
{
    int courseId = Marshal.ReadInt32(ptr);
    int count = Marshal.ReadInt32(ptr, Marshal.SizeOf(typeof(Int32)));

    // Set the int values
    Course course = new Course();
    course.Id = courseId;
    course.Count = count;

    // Now read out the Student structures
    ptr = new IntPtr(ptr.ToInt32() + (2 * Marshal.SizeOf(typeof(Int32))));
    for (int i = 0; i &amp;lt; count; i++)
    {
        Student student = (Student)Marshal.PtrToStructure(ptr, typeof(Student));
        course.Students[i] = student;
        ptr = new IntPtr(ptr.ToInt32() + Marshal.SizeOf(typeof(Student)));
    }

    return course;
}&lt;/PRE&gt;
&lt;P&gt;GetInstance() - This method is not a part of the ICustomMarshal interface but it's a &lt;STRONG&gt;static&lt;/STRONG&gt; method that must be implemented by any custom marashaler.&amp;nbsp; The runtime uses this to create an instance of the object.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Now we have a complete implementation of ICustomMarshal.&amp;nbsp; Really the only new method that we had to implement was MarshalManagedToNative() and that's just the opposite of what we did in part 3.&amp;nbsp; There are a couple of tidbits left that we have to alter.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The first is that we &lt;STRONG&gt;must&lt;/STRONG&gt; convert the managed Course from a struct to a class.&amp;nbsp; This is very important.&amp;nbsp; A custom marshaler can only be applied to reference types.&amp;nbsp; Changing Course to&amp;nbsp;a class has a couple of other implications as well.&amp;nbsp; Structs in C# are stored in the stack and reference types are stored on the heap.&amp;nbsp; This has implications to Marshalling as well.&amp;nbsp; When you Marshal&amp;nbsp;a struct (or any ValueType), the runtime is expecting to find a stack based value (or better, a non pointer value) on the Native end.&amp;nbsp; Now we are Marshalling a reference type so the runtime will expect to find a pointer value on the other end.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Also we can do away with the StructLayout attribute on the Course type.&amp;nbsp; We are hand Marshaling this now so we don't need to provide any hints to the runtime.&amp;nbsp; Now we are left with just a vanilla class.&amp;nbsp; &lt;/P&gt;&lt;PRE&gt;public class Course
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; public int Id;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int Count;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public List&amp;lt;Student&amp;gt; Students = new List&amp;lt;Student&amp;gt;(5);
}&lt;/PRE&gt;
&lt;P&gt;Now we just need to inform the runtime about how to link our custom marshaler (called CourseMarshaler in my code) to the Course class.&amp;nbsp; Every place that we declare a P/Invoke method we need to add custom Marshalling data.&amp;nbsp; This is done by adding the MarshalAs attribute.&amp;nbsp; Lets use the GetCourseInfo() method for an example.&amp;nbsp; Here is our updated definition.&lt;/P&gt;&lt;PRE&gt;[DllImport("Enrollment.dll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(CourseMarshaler))]
public static extern Course GetCourseInfo(int id);&lt;/PRE&gt;
&lt;P&gt;We've made two important changes here as well.&amp;nbsp; The first is we changed the return type of the method from an IntPtr to a Course.&amp;nbsp; Remember that this is a class now so the runtime is expecting a pointer value.&amp;nbsp; We take advantage of that here.&amp;nbsp; Also we've added the MarshalAs attribute to the return type to tell the runtime to use the Custom marshaler that we created.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;This makes the use code even cleaner since we aren't dealing with an IntPtr return type anymore.&amp;nbsp; &lt;/P&gt;&lt;PRE&gt;static void Main(string[] args)
{
    Course course = Enrollment.GetCourseInfo(42);
    Student first = course.Students[0];
}
&lt;/PRE&gt;
&lt;P&gt;That essentially concludes this series on Marshalling Nested Data Structures.&amp;nbsp; I may add an additional chapter on common tips for debugging common marshalling problems if I have some time.&amp;nbsp; Hope you enjoyed this.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;This posting is provided "AS IS" with no warranties, and confers no rights. &lt;BR&gt;Use of included script samples are subject to the terms specified at &lt;/FONT&gt;&lt;A title=http href="http://www.microsoft.com/info/cpyright.htm" mce_href="http://www.microsoft.com/info/cpyright.htm"&gt;&lt;FONT face=Verdana color=#223355 size=2&gt;&lt;STRONG&gt;http://www.microsoft.com/info/cpyright.htm&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt;.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=439457" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category></item><item><title>Marshaling Nested Data Structures Part 3</title><link>http://blogs.msdn.com/jaredpar/archive/2005/07/14/marshaling-nested-data-structures-part-3.aspx</link><pubDate>Fri, 15 Jul 2005 02:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:439024</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/439024.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=439024</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=439024</wfw:comment><description>&lt;P&gt;This is part&amp;nbsp;3 of a series.&amp;nbsp; You can find &lt;A href="http://blogs.msdn.com/jaredpar/archive/2005/07/11/437584.aspx" mce_href="http://blogs.msdn.com/jaredpar/archive/2005/07/11/437584.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;part one here&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt;.&amp;nbsp; Please refer to that article for all of the Native definitions of the structures that I use here.&lt;/P&gt;
&lt;P&gt;In part 2 of this series I demonstrated how you can Marshal nested data structures by flattening an array of structures into it's individual elements.&amp;nbsp; Using this is very awkward and is only practical when the size of your array is small.&amp;nbsp; This installment will get around these limitations with a bit of Marshalling help.&amp;nbsp; We'll get back indexing and remove the awkward flattening.&lt;/P&gt;
&lt;P&gt;Once again, don't forget that the only 2 things that matter when Marshalling data&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Byte Size 
&lt;LI&gt;Byte Layout &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;When an array of structures are declared as a member of a struct, in the same manner as the Course structure, the data is inlined after the first two ints.&amp;nbsp; We can get this data to Marshall properly by inserting a structure with the same size as the array of Students.&amp;nbsp; The Native Student Structure is 52 bytes so we need a 260 byte structure.&amp;nbsp; The following will do.&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Size = 260 )]
    public struct ArrayBlob
    {
    }

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct Course
    {
        public int Id;
        public int Count;
        public ArrayBlob Blob;

        /* ... Methods ... */
    }
&lt;/PRE&gt;
&lt;P&gt;This structure meets all of our requirments.&amp;nbsp; Course is now properly formatted and can be Marshalled back and forth successfully.&amp;nbsp; However our student array is stuck in a chunk of data that has no access methods.&amp;nbsp; This blob is just an array of students in memory.&amp;nbsp; Getting the Students out in C would be a snap.&amp;nbsp; We could just grab the address, cast it the the appropriate pointer and run away with the Student elements.&amp;nbsp; &lt;/P&gt;&lt;PRE&gt;Student *elements = (Student*)(&amp;amp;(myCourse.Blob); &lt;/PRE&gt;
&lt;P&gt;Unfortunately I'm giving these examples in Safe code so this is not allowed. You can get the same effect with C# although it's a bit slower and forces a memory allocation. We implement this as in indexer into the Course struct.&lt;/P&gt;&lt;PRE&gt;public Student this[int index]
        {
            get
            {
                if ( index &amp;gt;= Count )
                {
                    throw new ArgumentOutOfRangeException();
                }

                IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(ArrayBlob)));
                try
                {
                    Marshal.StructureToPtr(this.Blob, ptr, false);
                    int offset = index * Marshal.SizeOf(typeof(Student));
                    IntPtr structPtr = new IntPtr(ptr.ToInt32() + offset);
                    return (Student)Marshal.PtrToStructure(structPtr, typeof(Student));
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }&lt;/PRE&gt;
&lt;P&gt;Some error checking was removed for brevity sake.&amp;nbsp; Granted this is still a suboptimal way of accessing the members of the structure.&amp;nbsp; Every index requires an allocation.&amp;nbsp; But if you only interop for brief times and in non perf sensitive areas this code will do just fine.&amp;nbsp; Here's an example.&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;public static class Enrollment
    {
        [DllImport("Enrollment.dll", CharSet = CharSet.Unicode)]
        public static extern IntPtr CreateStudent(
            [MarshalAs(UnmanagedType.LPWStr)] String firstName,
            [MarshalAs(UnmanagedType.LPWStr)] String lastName,
            int bDay,
            int bMon,
            int bYear);

        [DllImport("Enrollment.dll", CharSet = CharSet.Unicode)]
        public static extern void UpdateStudentInfo(
            [MarshalAs(UnmanagedType.LPWStr)] String firstName,
            [MarshalAs(UnmanagedType.LPWStr)] String lastName,
            int bDay,
            int bMon,
            int bYear,
            ref Student student);

        [DllImport("Enrollment.dll", CharSet = CharSet.Unicode)]
        public static extern IntPtr GetCourseInfo(int id);
    }


    class MarshalFun
    {
        static void Main(string[] args)
        {
            IntPtr ptr = Enrollment.GetCourseInfo(42);
            Course course = (Course)Marshal.PtrToStructure(ptr, typeof(Course));

            Student first = course[0];
            Student second = course[1];
        }
    }
&lt;/PRE&gt;
&lt;P&gt;This code assumes that at least 2 students were returned from GetCourseInfo().&amp;nbsp; This code is much cleaner than the previous example.&amp;nbsp;&amp;nbsp;It will also work with very large sized arrays.&amp;nbsp; However it does have undue perf and memory overhead.&amp;nbsp; Next time we'll look at a way to have the clean code and remove all of the perf problems present in the current code.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;This posting is provided "AS IS" with no warranties, and confers no rights. &lt;BR&gt;Use of included script samples are subject to the terms specified at &lt;/FONT&gt;&lt;A title=http href="http://www.microsoft.com/info/cpyright.htm" mce_href="http://www.microsoft.com/info/cpyright.htm"&gt;&lt;FONT face=Verdana color=#223355 size=2&gt;&lt;STRONG&gt;http://www.microsoft.com/info/cpyright.htm&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt;.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=439024" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category></item><item><title>Marshaling Nested Data Structures Part 2</title><link>http://blogs.msdn.com/jaredpar/archive/2005/07/12/marshaling-nested-data-structures-part-2.aspx</link><pubDate>Tue, 12 Jul 2005 18:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:437686</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/437686.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=437686</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=437686</wfw:comment><description>&lt;P&gt;This is part 2 of a series.&amp;nbsp; You can find &lt;A href="http://blogs.msdn.com/jaredpar/archive/2005/07/11/437584.aspx" mce_href="http://blogs.msdn.com/jaredpar/archive/2005/07/11/437584.aspx"&gt;part one here&lt;/A&gt;.&amp;nbsp; Please refer to that article for all of the Native definitions of the structures that I use here.&lt;/P&gt;
&lt;P&gt;The most important thing to remember when Marshalling data is that the .Net Runtime really only cares about byte layout and how many bytes you are trying to move.&amp;nbsp; If you mangle your managed structure to match the byte size and layout&amp;nbsp;of your unmanaged structure, the runtime will Marshal it sucessfully almost all of the time.&amp;nbsp; Note by successfully I mean that the method will complete without causing the dreaded AccessViolationException but the data might not be quite what you were expecting.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;For example.&amp;nbsp; Here is the typical managed definition for the Student struct definition.&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct Student
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
        public string FirstName;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
        public string LastName;

        public int BirthDay;
        public int BirthMonth;
        public int BirthYear;
    }
&lt;/PRE&gt;
&lt;P&gt;Notice that the size of this structure is 52 bytes.&amp;nbsp; &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;FirstName 2 (size of char) * 10 (size of array) 
&lt;LI&gt;LastName 2 (size of char) * 10 (size of array) 
&lt;LI&gt;12 bytes (4 bytes for each of the int's)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;This is the same size as the native definiton of Student.&amp;nbsp; In memory these bytes will all appear in order with no spaces between them (FirstName and LastName are set as ByValTStr's so they will be inlined).&amp;nbsp; So LastName is 20 bytes offset of a student structure, BirthDay is 40 bytes offset and so on.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;You don't always have to be so perfect though.&amp;nbsp; In this case it's only important because we want to accesss the fields of the managed structure.&amp;nbsp; If this was not important to us, we could have just as easily declared the structure as so.&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;    [StructLayout(LayoutKind.Sequential, Size = 52, CharSet = CharSet.Unicode)]
    public struct Student
    { 

    }
&lt;/PRE&gt;
&lt;P&gt;Note that i didn't leave anything out in the structure above.&amp;nbsp; It has the correct CharSet and Size so this could be successfully used wherever we need the Student structure.&amp;nbsp; It just doesn't help us very much in Managed code :) &lt;/P&gt;
&lt;P&gt;Now onto the Course.&amp;nbsp; A lot of developers get tripped up when trying to define structs like Course in managed code.&amp;nbsp; Don't forget, all we need to do is get the bytes correct and the Marshaller will work out the rest.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This structure is very small.&amp;nbsp; There are only 5 inlined elements in the student array.&amp;nbsp; This means that we could easily define our structure as so.&amp;nbsp; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct Course
    {
        public int Id;
        public int Count;
        Student Student0;
        Student Student1;
        Student Student2;
        Student Student3;
        Student Student4;
    }
&lt;/PRE&gt;
&lt;P&gt;I realize there are several downsides to defining our structure like this.&amp;nbsp; For one, it doesn't look very clean.&amp;nbsp; Secondly we've lost the ability to easily index the array of students.&amp;nbsp; Also this works easily because there are only 5 elements in the array.&amp;nbsp; If there were much more than that this wouldn't be pheasible at all.&amp;nbsp; However this structure is layed out exactly like the one defined in Native code so this will Marshal correctly.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The next part to this series will try to make things a bit more pleasing to the eye. We'll get back indexing at the cost of&amp;nbsp;a bit of manual Marshalling.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;This posting is provided "AS IS" with no warranties, and confers no rights. &lt;BR&gt;Use of included script samples are subject to the terms specified at &lt;/FONT&gt;&lt;A title=http href="http://www.microsoft.com/info/cpyright.htm" mce_href="http://www.microsoft.com/info/cpyright.htm"&gt;&lt;FONT face=Verdana color=#223355 size=2&gt;&lt;STRONG&gt;http://www.microsoft.com/info/cpyright.htm&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt;.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=437686" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category></item><item><title>Marshaling Nested Data Structures Part 1</title><link>http://blogs.msdn.com/jaredpar/archive/2005/07/11/marshaling-nested-data-structures-part-1.aspx</link><pubDate>Mon, 11 Jul 2005 19:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:437584</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/437584.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=437584</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=437584</wfw:comment><description>&lt;P&gt;A frequent question that pops up on newsgroups such as microsoft.dotnet.framework.interop is how to Marshal nested structures (and arrays of nested structures) via P/Invoke.&amp;nbsp; The documentation on the subject that I have found usually only covers structures that&amp;nbsp;defined in the UnmanagedType enumeration&amp;nbsp;and just touch on the idea of structures containing nested arrays of custom structures.&amp;nbsp; Part of the reason is that the explinations for these problems is quite involed and scenario specific.&amp;nbsp; After answering it a few times I decided to make a multi part blog post on the subject.&amp;nbsp; This will consist of at least 4 entries (might add some more if something comes up).&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Index&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/jaredpar/archive/2005/07/12/437686.aspx" mce_href="http://blogs.msdn.com/jaredpar/archive/2005/07/12/437686.aspx"&gt;Part Two&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/jaredpar/archive/2005/07/14/439024.aspx" mce_href="http://blogs.msdn.com/jaredpar/archive/2005/07/14/439024.aspx"&gt;Part Three&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/jaredpar/archive/2005/07/18/439457.aspx" mce_href="http://blogs.msdn.com/jaredpar/archive/2005/07/18/439457.aspx"&gt;Part Four&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The first installment is just going to be laying out our Native data structures that will be used throughout this series.&amp;nbsp; I'm going to use a generic(and quite contrived) university classroom examle.&amp;nbsp; Here are the C struct definitions and a couple of functions that I will be using.&amp;nbsp; &lt;/P&gt;&lt;PRE&gt;struct Student 
{ 
  WCHAR FirstName[10]; 
  WCHAR LastName[10]; 
  int BirthDay; 
  int BirthMonth; 
  int BirthYear; 
}; 

struct Course{ 
  int Id; 
  int Count; 
  Student Students[5]; 
}; 

	// Create a student with the specified information.  Returned structure should be freed with 
	// GlobalFree
__declspec(dllexport) Student* CreateStudent(
    LPCWSTR firstName, 
    LPCWSTR lastName, 
    int bDay, 
    int bMon, 
    int bYear)

	// Update an existing student with the specified information
__declspec(dllexport) void UpdateStudentInfo(
    LPCWSTR firstName, 
    LPCWSTR lastName, 
    int bDay, 
    int bMon, 
    int bYear, 
    Student *student)

	// Get information for a particurlar course.  Returned structure should be freed with 
	// GlobalFree
__declspec(dllexport) Course *GetCourseInfo(int courseId)

&lt;/PRE&gt;
&lt;P&gt;The environment I am coding and testing my fixes in is Microsoft Visual Studio 2005 Beta 2. All of these examples should work in all versions of Visual Studio though.&amp;nbsp; If you find an inconsistencies please let me know.&amp;nbsp; All native examples will also be in Unicode.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;This posting is provided "AS IS" with no warranties, and confers no rights. &lt;BR&gt;Use of included script samples are subject to the terms specified at &lt;/FONT&gt;&lt;A title=http href="http://www.microsoft.com/info/cpyright.htm" mce_href="http://www.microsoft.com/info/cpyright.htm"&gt;&lt;FONT face=Verdana color=#223355 size=2&gt;&lt;STRONG&gt;http://www.microsoft.com/info/cpyright.htm&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt;.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=437584" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category></item><item><title>Interop and Unions</title><link>http://blogs.msdn.com/jaredpar/archive/2005/05/13/interop-and-unions.aspx</link><pubDate>Fri, 13 May 2005 18:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:417263</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/417263.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=417263</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=417263</wfw:comment><description>&lt;P&gt;A frequent question I see pop up on news groups is how to create Unions in managed code for interop with P/Invoke.&amp;nbsp; .NET does not &lt;EM&gt;directly&lt;/EM&gt; support unions but you can use some Marshal magic to get them working.&amp;nbsp; Take the following C union.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;union Foo&lt;/P&gt;
&lt;P&gt;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;int a;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;float b;&lt;/P&gt;
&lt;P&gt;}&lt;/P&gt;
&lt;P&gt;Really what this translates to in the native world is a data structure that is 4 bytes long (the key to Marshalling is never forgetting that you are just dealing with bytes).&amp;nbsp; To simulate this in .NET you could probably get away with creating a structure that is 4 bytes long and passing that in.&amp;nbsp; You'd loose the easy type switch that you get with unions but it would most likely work.&amp;nbsp; To get the nice type switch you do the following. &lt;/P&gt;
&lt;P&gt;[StructLayout(LayoutKind.Explicit)]&lt;/P&gt;
&lt;P&gt;public struct ManagedFoo&lt;/P&gt;
&lt;P&gt;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;[FieldOffset(0)] int a;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;[FieldOffset(0)] float b;&lt;/P&gt;
&lt;P&gt;}&lt;/P&gt;
&lt;P&gt;The attributes here will cause the fields to both be aligned at the very begining of the structure.&amp;nbsp; This gives you the benefits of a Union in C# and the compatibility to Marshall with P/Invoke.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;There is one catch with this technique.&amp;nbsp; You cannot mix value and reference types in a Managed union.&amp;nbsp; If you do you will get a nasty type load exception at runtime.&amp;nbsp; The best work around in that case is to use an IntPtr in place of the reference types and do some additional Marshalling on that field.&amp;nbsp; &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=417263" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PInvoke/default.aspx">PInvoke</category></item></channel></rss>