C #에서 포인터를 실제로 사용합니까? [닫은]


19

포인터를 사용하는 것이 좋거나 필요한 옵션 인 C #으로 코딩하는 동안 상황은 무엇입니까? 안전하지 않은 포인터 에 대해 이야기하고 있습니다.


8
Ahhh man, 나는 C #에서 포인터를 항상 사용한다고 설명 할 것이기 때문에 질문을 보았고 모두 행복 해졌다.하지만 안전하지 않은 키워드를 명시 적으로 말함으로써 그것을 망쳐 놓아야했다. 댕! :)
Tony

답변:


25

C # 개발자 자신으로부터 :

C #에서는 포인터 사용이 거의 필요하지 않지만 몇 가지 상황이 필요합니다. 예를 들어, 안전하지 않은 컨텍스트를 사용하여 포인터를 허용하는 것은 다음과 같은 경우에 보증됩니다.

  • 디스크의 기존 구조 다루기
  • 포인터가있는 구조를 포함하는 고급 COM 또는 플랫폼 호출 시나리오
  • 성능이 중요한 코드

다른 상황에서는 안전하지 않은 컨텍스트를 사용하지 않는 것이 좋습니다.

특히 안전하지 않은 컨텍스트를 사용하여 C #으로 C 코드를 작성하려고 시도해서는 안됩니다.

주의 : "안전하지 않은 컨텍스트를 사용하여 작성된 코드는 안전하다고 확인할 수 없으므로 코드를 완전히 신뢰할 때만 실행됩니다. 즉, 신뢰할 수없는 환경에서는 안전하지 않은 코드를 실행할 수 없습니다. 예를 들어, 안전하지 않은 코드는 실행할 수 없습니다 인터넷에서 직접 코드를 작성하십시오. "

당신은 참조를 위해 이것을 통해 갈 수 있습니다


"신뢰할 수없는 환경에서는 안전하지 않은 코드를 실행할 수 없습니다." "신뢰"를 의미 했습니까?
Don Larynx

18

예, 성능이 중요하고 작업 수준이 낮은 경우 실제 용도가 있습니다

예를 들어, 이미지 비교를 위해 C #에서 포인터를 한 번만 사용해야했습니다. 1024x1024x32 이미지 쌍에서 GetPixel을 사용하면 비교를 수행하는 데 2 ​​분이 걸렸습니다 (정확한 일치). 이미지 메모리를 고정하고 포인터를 사용하는 데 1 초도 걸리지 않았습니다 (물론 동일한 컴퓨터에서).


2
이를 위해 LockBits를 사용하셨습니까? ( msdn.microsoft.com/en-us/library/… )
구성자

1
@configurator :이 LockBits이 존재하지 않았다, 2 .NET했다
스티븐 A. 로우

2
물론, 1.0 이후로 존재했습니다 ...
구성자

@ configurator : 내 오류, MSDN 설명서를 탐색하는 것이 혼란스러워졌습니다 (드롭리스트에서 .net 2로 변경하면 잠금 비트를 언급하지 않은 완전히 다른 페이지로 이동했습니다). 예, 이미지 메모리를 고정하는 방법입니다.
Steven A. Lowe

6

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;
        }
    }
}

1
유스 케이스가 1 개이기 때문에 일부 기능을 포함하면 개발자 (Microsoft 또는 다른 회사의 개발자)가 바보가 될 것이라고 말하고 싶습니다. 기능은 사용 사례가 1 개 이상이어야합니다. 그렇지 않으면 그것은 팽창입니다.
Lie Ryan

4
Raymond Chen은 종종 Microsoft의 기능이 -100 "포인트"에서 시작한다고 말했습니다. 기능을 구현하려면 "전체 패키지에 적용 할 수있는 실질적인 효과가 있어야합니다". 이 c.2004에 대한 ericgu의 블로그 게시물은 다음과 같습니다. blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx
Jesse Buchanan

일부 String 작업은 내부적으로 안전하지 않은 코드를 사용한다고 확신합니다. 따라서 FParsec이 우선 순위가 아닐 수 있습니다.
Arturo Torres Sánchez

4

한 번 헤드셋에 대한 인터페이스 역할을하는 C # 기반 Windows 응용 프로그램에서 안전하지 않은 컨텍스트에서 포인터를 사용해야했습니다. 이 응용 프로그램은 (콜 센터의) 상담원이 자신의 헤드폰 설정을 제어 할 수 있도록하는 사용자 인터페이스입니다. 이 응용 프로그램은 헤드셋 제조업체에서 제공 한 제어판 대신 사용할 수 있습니다. 따라서 사용 가능한 옵션과 비교할 때 헤드셋을 제어하는 ​​기능이 제한되었습니다. P / Invoke를 사용하여 헤드셋 제조업체에서 제공 한 API (Visual C ++ dll)를 사용해야했기 때문에 포인터를 사용해야했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.