Inside C# 4 Data Structs
Inside C# 4 Data Structs
Tuesday, 07 September 2010
Article Index
Inside C# 4 Data Structs
Being exact
Serialising structs
Manual mashaling




Now that we have mastered the manual marshaling of a simple pointer to a struct the next step is a pointer to a pointer to a struct. Surprisingly this requires nothing new because the struct-to-pointer function will actually convert any data type to an unmanaged pointer – including a pointer.

The  function AVISaveOption is a suitable example as it needs two pointers to pointers as parameters:

extern static int AVISaveOptions(
IntPtr hWnd,
int uiFlags,
int noStreams,
IntPtr ppavi,
IntPtr ppOptions);

In fact the ppavi parameter is a pointer to a handle (which is itself a pointer) and the ppOptions is a pointer to a pointer to a struct. To call this function we first need the struct:


You can look up the definition of the structure in the standard AVI documentation.

Next we need the marshaled pointer to the struct:

IntPtr lpstruct = MarshalToPointer(opts);

and then the pointer to the pointer:

IntPtr lppstruct = MarshalToPointer(

followed by the pointer to the handle:

IntPtr lphandle = MarshalToPointer(

The call to the API function is now simple:

result = AVISaveOptions(

where the other parameters and constants aren’t of any great interest to us and you can find more details in the API’s documentation.

When the function completes all that is left to do is transfer the data in the unmanaged buffer back into the managed struct:


You have to be careful to use the pointer to the struct and not the pointer to the pointer!

Finally we can free all of the unmanaged memory we used:


This might all seem complicated. Using pointers-to-pointers is never an easy thing to do and it is one of the reasons that C# makes sure that when you do use pointers then you mark the code as unsafe. However you might like to contemplate just how safe this sort of juggling is and all without an unsafe block in sight.

On the other hand the general principles are very simple. When you pass anything by ref to an API it has to be copied to unmanaged memory and the address of this memory is passed to the function. Normally default marshaling takes care of this and you can ignore it - but it still happens. If you need to go beyond what is provided by the marshaling attributes then you have to perform this copying explicitly.


Deep C# - Value And Reference

Value and reference are a fundamental division in the way C# treats data. It is important that you understand the differences and most importantly when to use a struct and when to use a class. These a [ ... ]

Custom Attributes In C#

The role of custom attributes in C# can be confusing. They are easy to use when supplied, but how do you go about creating custom attributes? And when are they useful? 

Other Articles






Last Updated ( Tuesday, 28 September 2010 )

RSS feed of all content
I Programmer - full contents
Copyright © 2015 All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.