문제

누군가 C# 코드에서 "안전하지 않음"과 "고정"을 실제로 사용하기에 좋은 예를 들어줄 수 있습니까?나는 이전에 그것을 가지고 놀았지만 실제로 좋은 용도를 찾지 못했습니다.

이 코드를 고려해보세요...

fixed (byte* pSrc = src, pDst = dst) {
    //Code that copies the bytes in a loop
}

그냥 사용하는 것에 비해..

Array.Copy(source, target, source.Length);

두 번째는 .NET Framework에 있는 코드입니다. 첫 번째는 Microsoft 웹사이트에서 복사한 코드의 일부입니다. http://msdn.microsoft.com/en-us/library/28k1s2k6(VS.80).aspx.

내장된 Array.Copy()는 안전하지 않은 코드를 사용하는 것보다 훨씬 빠릅니다.이는 단지 두 번째가 더 잘 작성되었고 첫 번째는 단지 예일 뿐이기 때문일 수도 있지만 실제로 안전하지 않은/고정 코드를 어떤 용도로든 사용해야 하는 상황은 무엇입니까?아니면 이 불쌍한 웹 개발자가 머리 위의 무언가를 조작하고 있는 걸까요?

도움이 되었습니까?

해결책

비관리 코드와의 상호 운용에 유용합니다.관리되지 않는 함수에 전달된 모든 포인터는 수정되어야 합니다(일명.고정) 가비지 수집기가 기본 메모리를 재배치하는 것을 방지합니다.

P/Invoke를 사용하는 경우 기본 마샬러가 개체를 고정합니다.사용자 지정 마샬링을 수행해야 하는 경우도 있고, 단일 P/Invoke 호출 기간보다 오랫동안 개체를 고정해야 하는 경우도 있습니다.

다른 팁

비트맵 데이터를 조작하기 위해 안전하지 않은 블록을 사용했습니다.원시 포인터 액세스는 SetPixel/GetPixel보다 훨씬 빠릅니다.

unsafe
{
    BitmapData bmData = bm.LockBits(...)
    byte *bits = (byte*)pixels.ToPointer();
    // Do stuff with bits
}

"고정" 및 "안전하지 않음"은 일반적으로 상호 운용성을 수행하거나 추가 성능이 필요할 때 사용됩니다.즉.String.CopyTo()는 구현 시 안전하지 않고 수정됨을 사용합니다.

reinterpret_cast 스타일 동작

조금 조작하는 경우 이것은 매우 유용할 수 있습니다.

많은 고성능 해시코드 구현에서는 해시 값으로 UInt32를 사용합니다(이렇게 하면 전환이 더 간단해집니다)..Net에서는 단위를 int로 빠르게 변환하려는 방법에 Int32가 필요합니다.실제 값이 무엇인지는 중요하지 않으므로 값의 모든 비트가 보존되는 것만 재해석된 캐스트가 필요합니다.

public static unsafe int UInt32ToInt32Bits(uint x)
{
    return *((int*)(void*)&x);
}

이름은 다음을 모델로 한 것입니다. BitConverter.DoubleToInt64Bits

해싱 방식으로 계속해서 스택 기반 구조체를 바이트*로 변환하면 바이트당 해싱 기능을 쉽게 사용할 수 있습니다.

// from the Jenkins one at a time hash function
private static unsafe void Hash(byte* data, int len, ref uint hash)
{
    for (int i = 0; i < len; i++)
    {
        hash += data[i];
        hash += (hash << 10);
        hash ^= (hash >> 6);
    }
}

public unsafe static void HashCombine(ref uint sofar, long data)
{
    byte* dataBytes = (byte*)(void*)&data;
    AddToHash(dataBytes, sizeof(long), ref sofar);
}

unsafe 또한 (2.0부터) stackalloc을 사용할 수 있습니다.이는 임시 공간과 같은 작은 가변 길이 배열이 필요한 고성능 상황에서 매우 유용할 수 있습니다.

이러한 모든 용도는 '응용 프로그램에 실제로 성능이 필요한 경우에만' 확실하게 적용되므로 일반적인 사용에는 부적절하지만 때로는 실제로 필요한 경우도 있습니다.

C 스타일 배열이나 문자열을 사용하는 유용한 관리되지 않는 함수(많음)와 상호 운용하려는 경우 고정이 필요합니다.따라서 이는 성능상의 이유뿐만 아니라 상호 운용성 시나리오의 정확성 때문이기도 합니다.

안전하지 않음은 예를 들어 LockBits를 사용하여 이미지에서 픽셀 데이터를 빠르게 가져오는 데 유용합니다.관리형 API를 사용하여 이 작업을 수행하는 것보다 성능이 몇 배나 향상됩니다.

주소가 레거시 C DLL로 전달될 때 고정을 사용해야 했습니다.DLL은 함수 호출 전반에 걸쳐 내부 포인터를 유지했기 때문에 GC가 힙을 압축하고 항목을 이동하면 모든 것이 풀릴 것입니다.

.NET 런타임 외부의 항목에 액세스하려는 경우 안전하지 않은 코드가 사용된다고 생각합니다.관리되는 코드가 아닙니다(가비지 수집 등 없음).여기에는 Windows API에 대한 원시 호출과 모든 재즈가 포함됩니다.

이는 .NET 프레임워크의 디자이너가 "관리 코드" 환경이 기존 방식(예:C++) 접근 방식은 안전하지 않은 코드/포인터를 사용할 수 있습니다.그렇게 할 수 없는 경우 필요한 경우 안전하지 않거나 수정된 ​​기능이 있습니다.안전하지 않은 코드가 필요한 예가 누군가 있다고 확신하지만 실제로는 드문 것 같습니다. 오히려 요점이 아닌가요?:)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top