Unsafe Code


C# allows the user to use a limited version of "inline C" to write pointer-based code.

To safely use pointers in a garbage-collected (GC) environment, there needs to be a mechanism to prevent GC-tracked objects from being relocated by the garbage collector. The runtime environment allows objects to be pinned in place, then exposed in C# in a declarative manner using the fixed statement. The example in Listing B.1 uses an unsafe context to sum up the bytes in a byte array.

Listing B.1
 static unsafe int DoSum(byte[] byteBuffer) {     int length = byteBuffer.Length;     int sum = 0;     fixed (byte* pBuffer = byteBuffer)     {         byte* pCurrent = pBuffer;         while (pCurrent < pBuffer + length)         {             sum += *pCurrent;             pCurrent++;         }     }     return sum; } 

The fixed statement pins the byteBuffer instance in place so that its address can be safely obtained, and then the code inside the fixed block uses traditional pointer arithmetic. At the end of the fixed block, the byteBuffer will be unpinned, and fixed generates a try - finally block to ensure that this happens.

The use of pointers in an unsafe block prevents the IL verifier from verifying that this code is safe, and the machine security policy will prevent the execution of such code in scenarios such as downloaded code. In the current versions of C#, this issue is handled at an assembly level, so any use of unsafe code within an assembly marks the entire assembly as unsafe.

There are three main scenarios where unsafe code is typically used: advanced interoperability, dealing with existing structures, and performance extremes.

Advanced Interoperability

Some native and COM interfaces use pointers in their definitions in a manner that is not supported by the data marshaller. In these cases, being able to use pointers as part of COM Interop enables this code to be used directly from C# without having to write a wrapper using the Managed Extensions to C++. [8]

[8] Sometimes such a wrapper may still be required, and using the Managed Extensions can often be easier than using the equivalent unsafe code in C#, especially in complex cases.

Dealing with Existing Structures

Disk files may contain structures with a specific definition, or network protocols may define a specific block structure for a message. Using unsafe code allows a structure to be overlaid on top of a buffer read from the disk or network, instead of requiring the programmer to code reading each field individually.

Performance Extremes

In some cases, the overhead of accessing data through the managed environment may be too high, or an existing library may expect the power user to access data directly using pointer arithmetic. In such cases, it's important to consider the scenario carefully , as using pointers isn't always the best (or fastest ) choice.



Programming in the .NET Environment
Programming in the .NET Environment
ISBN: 0201770180
EAN: 2147483647
Year: 2002
Pages: 146

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net