답변:
C # 개발자 자신으로부터 :
C #에서는 포인터 사용이 거의 필요하지 않지만 몇 가지 상황이 필요합니다. 예를 들어, 안전하지 않은 컨텍스트를 사용하여 포인터를 허용하는 것은 다음과 같은 경우에 보증됩니다.
- 디스크의 기존 구조 다루기
- 포인터가있는 구조를 포함하는 고급 COM 또는 플랫폼 호출 시나리오
- 성능이 중요한 코드
다른 상황에서는 안전하지 않은 컨텍스트를 사용하지 않는 것이 좋습니다.
특히 안전하지 않은 컨텍스트를 사용하여 C #으로 C 코드를 작성하려고 시도해서는 안됩니다.
주의 : "안전하지 않은 컨텍스트를 사용하여 작성된 코드는 안전하다고 확인할 수 없으므로 코드를 완전히 신뢰할 때만 실행됩니다. 즉, 신뢰할 수없는 환경에서는 안전하지 않은 코드를 실행할 수 없습니다. 예를 들어, 안전하지 않은 코드는 실행할 수 없습니다 인터넷에서 직접 코드를 작성하십시오. "
당신은 참조를 위해 이것을 통해 갈 수 있습니다
예, 성능이 중요하고 작업 수준이 낮은 경우 실제 용도가 있습니다
예를 들어, 이미지 비교를 위해 C #에서 포인터를 한 번만 사용해야했습니다. 1024x1024x32 이미지 쌍에서 GetPixel을 사용하면 비교를 수행하는 데 2 분이 걸렸습니다 (정확한 일치). 이미지 메모리를 고정하고 포인터를 사용하는 데 1 초도 걸리지 않았습니다 (물론 동일한 컴퓨터에서).
Microsoft의 디자이너는 똑똑한 사람이며 C #에 추가하는 모든 것은 적어도 하나의 유스 케이스를 가지고 있음을 기억해야합니다. FParsec 프로젝트는 C #이 할 수 있는지 성능의 모든 마지막 한 방울을 이끌어에 안전하지 않은 코드를 사용합니다. fixed
및 사용법에 유의하십시오 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;
}
}
}
한 번 헤드셋에 대한 인터페이스 역할을하는 C # 기반 Windows 응용 프로그램에서 안전하지 않은 컨텍스트에서 포인터를 사용해야했습니다. 이 응용 프로그램은 (콜 센터의) 상담원이 자신의 헤드폰 설정을 제어 할 수 있도록하는 사용자 인터페이스입니다. 이 응용 프로그램은 헤드셋 제조업체에서 제공 한 제어판 대신 사용할 수 있습니다. 따라서 사용 가능한 옵션과 비교할 때 헤드셋을 제어하는 기능이 제한되었습니다. P / Invoke를 사용하여 헤드셋 제조업체에서 제공 한 API (Visual C ++ dll)를 사용해야했기 때문에 포인터를 사용해야했습니다.