What is a situation while coding in C# where using pointers is a good or necessary option? I'm talking about unsafe pointers.
4 Answers
From the developer of C# himself:
The use of pointers is rarely required in C#, but there are some situations that require them. As examples, using an unsafe context to allow pointers is warranted by the following cases:
- Dealing with existing structures on disk
- Advanced COM or Platform Invoke scenarios that involve structures with pointers in them
- Performance-critical code
The use of unsafe context in other situations is discouraged.
Specifically, an unsafe context should not be used to attempt to write C code in C#.
Caution: "Code written using an unsafe context cannot be verified to be safe, so it will be executed only when the code is fully trusted. In other words, unsafe code cannot be executed in an untrusted environment. For example, you cannot run unsafe code directly from the Internet."
You may go through this for reference
-
"unsafe code cannot be executed in an untrusted environment." Did you mean "trusted"? Apr 6, 2015 at 1:18
yes, there are real uses, when performance is critical and the operations are low-level
for example, i've only needed to use pointers in C# once, for image comparison. Using GetPixel on a pair of 1024x1024x32 images took 2 minutes to do the comparison (Exact match). Pinning the image memory and using pointers took less than 1 second (on the same machine of course).
-
2I have you used LockBits for that... ( msdn.microsoft.com/en-us/library/… ) Dec 19, 2010 at 15:39
-
1
-
2
-
@configurator: my error, i got confused navigating the MSDN documentation (when i changed to .net 2 in the droplist it went to a completely different page that did not mention lockbits). Yes, that's how you pin the image memory. Dec 20, 2010 at 3:05
You have to remember that the designers at Microsoft are smart people and everything they add to C# has at least 1 use case. The FParsec project uses unsafe code to bring out every last drop of performance that C# is capable of. Take notice of the usage of fixed
and stackalloc
.
private char* ReadCharsFromStream(char* buffer, int maxCount, out string overhangChars) {
Debug.Assert(maxCount >= 0);
fixed (byte* byteBuffer = ByteBuffer) {
overhangChars = null;
try {
while (maxCount >= MaxCharCountForOneByte) {// if maxCount < MaxCharCountForOneByte, Convert could throw
int nBytesInByteBuffer = FillByteBuffer();
bool flush = nBytesInByteBuffer == 0;
int bytesUsed, charsUsed; bool completed = false;
Decoder.Convert(byteBuffer + ByteBufferIndex, nBytesInByteBuffer,
buffer, maxCount, flush,
out bytesUsed, out charsUsed, out completed);
ByteBufferIndex += bytesUsed; // GetChars consumed bytesUsed bytes from the byte buffer
buffer += charsUsed;
maxCount -= charsUsed;
if (flush && completed) return buffer;
}
if (maxCount == 0) return buffer;
char* cs = stackalloc char[MaxCharCountForOneByte];
for (;;) {
int nBytesInByteBuffer = FillByteBuffer();
bool flush = nBytesInByteBuffer == 0;
int bytesUsed, charsUsed; bool completed;
Decoder.Convert(byteBuffer + ByteBufferIndex, nBytesInByteBuffer,
cs, MaxCharCountForOneByte, flush,
out bytesUsed, out charsUsed, out completed);
ByteBufferIndex += bytesUsed;
if (charsUsed > 0) {
int i = 0;
do {
*(buffer++) = cs[i++];
if (--maxCount == 0) {
if (i < charsUsed) overhangChars = new string(cs, i, charsUsed - i);
return buffer;
}
} while (i < charsUsed);
}
if (flush && completed) return buffer;
}
} catch (DecoderFallbackException e) {
e.Data.Add("Stream.Position", ByteIndex + e.Index);
throw;
}
}
}
-
1I'd say the developers (at Microsoft or any other companies) would be an idiot if they included some feature because it has 1 use case. A feature should have much more than just 1 use cases; otherwise it is a bloat.– Lie RyanDec 8, 2010 at 15:51
-
4Raymond Chen has often said that features at Microsoft start at -100 "points". In order a feature to be implemented, it "has to have a significant net positive effect on the overall package for it to make it in". Here's ericgu's blog post about this c.2004: blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx Dec 14, 2010 at 20:19
-
I'm pretty sure some String operations internally use unsafe code. So, FParsec may not have been the priority. May 17, 2016 at 15:38
I once had to use pointers (in the unsafe context) in a C# based windows application that would act as an interface to a headset. This application is a user interface that would allow agents (at a call center) to control their headphone settings. This application acts as an alternate to the control panel given by the headset manufacturer. Thus, their ability to control the headsets were limited when compared to the options available. I had to use pointers because I had to use the API (a Visual C++ dll) provided by the headset manufacturer using P/Invoke.