intptr이 필요한 메소드를 호출하려면 사용 /안전하지 않거나 Marshal.allochglobal을 사용하는 것이 좋습니다.

StackOverflow https://stackoverflow.com/questions/1682776

문제

응용 프로그램 기간 동안 몇 가지 인스턴스가 지속될 수있는 수업이 있습니다. 이 객체는 각각 기존 Float [] 버퍼의 데이터를 추가하는 DLL 메소드를 호출하고 전체 데이터 세트를 초당 여러 번 intptr (float array)를 수용하는 DLL 메소드로 전달해야합니다. 관리되지 않는 코드로 수행하는 것이 좋습니다.



    class PersistentThing : IDisposable {
        readonly IntPtr _floats = Marshal.AllocHGlobal(sizeof(float) * ArraySize);

        public void DoFrequentAction() {
            // Append data from a buffer to the memory space.
            var floatOffsetPtr = new IntPtr(_floats.ToInt32() + _floatsIndex * sizeof(float));
            Marshal.Copy(_buffer, _bufferIndex, floatOffsetPtr, _bufferCount);

            // Call a DLL method with with memory pointer
            CallDllMethod(_floats);
        }

        // Need to dispose the unmanaged memory
        public void Dispose() {
            Marshal.FreeHGlobal(_floats);
        }
    }

아니면 안전하지 않은 태그를 사용하고 고정하는 것이 더 낫습니까?


    class PersistentThing2 {
        readonly float[] _floats = new float[ArraySize];

        public unsafe void DoFrequentAction() {
            // Append data from a buffer to the memory space.
            Array.Copy(_buffer, _bufferIndex, _floats, _floatsIndex, _bufferCount);

            // Call a DLL method with with memory pointer
            fixed (float* floatsPtr = _floats) {
                CallDllMethod((IntPtr)floatsPtr);
            }
        }
    }

컴파일러에서 "안전하지 않은"태그를 사용할 필요가 없다는 장점이 있습니까? 원수 클래스는 실제로 "더 안전한"입니까? 이러한 방법 중 일반적으로 성능이 향상되는 방법은 무엇입니까?

나는 GC가 걱정할 필요가 없기 때문에 전자에 기대어 _floats 메모리 공간을 청소할 때 (상당히 클 수 있습니다). 그것이 합리적인 관심사입니까? 권장 사항은 배열 크기에 따라 다릅니 까?

도움이 되었습니까?

해결책 2

나는 궁극적으로 두 솔루션이 모두 괜찮다는 것을 알게되었습니다. 성능은 거의 동일하며 GC는 두 번째 솔루션에 영향을 미치지 않습니다. 물체는 큰 물체 힙에 할당되고 결코 움직이지 않거나 가비지 수집가의 2 세대로 빠르게 홍보되고 거의 움직이지 않기 때문입니다. .

다른 팁

두 경우 모두, 당신은 기본의 안전하지 않은 코드라고 부릅니다.

두 번째 옵션을 선호합니다. 깨끗하고 따라 가기 쉽고 더 분명합니다. 또한 배열을 수집 할 수 있도록 Idisposable을 강요하지 않습니다.

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