관리되는 메모리에 배열을 할당 한 다음 GCHandle
을 만들어 관리되지 않는 메모리에서 액세스 할 수있게 할 수도 있습니다.
예를 들어 여기서 PowerReadACValue
을 호출합니다. Win32 API 함수는 LPBYTE
버퍼 (이는 BYTE*
과 같습니다)를 사용합니다.
먼저 "null 포인터"(IntPtr.Zero)를 호출하여 필요한 크기 버퍼를 알려줍니다 (bufferSize로 출력 됨). 그런 다음 버퍼를 할당하고 GCHandle
의 AddrOfPinnedObject
을 통해 포인터를 전달합니다.
uint type;
uint bufferSize = 0;
if (SafeNativeMethods.PowerReadACValue(IntPtr.Zero, this.m_planHandle, ref subGroupOfPowerSettingsGuid, ref powerSettingGuid, out type, IntPtr.Zero, ref bufferSize) != 0)
{
throw new Win32Exception();
}
byte[] buffer = new byte[bufferSize];
GCHandle bufferPointer = default(GCHandle);
try
{
bufferPointer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
if (SafeNativeMethods.PowerReadACValue(IntPtr.Zero, this.m_planHandle, ref subGroupOfPowerSettingsGuid, ref powerSettingGuid, out type, bufferPointer.AddrOfPinnedObject(), ref bufferSize) != 0)
throw new Win32Exception();
}
finally
{
if (bufferPointer.IsAllocated)
bufferPointer.Free();
}
또한, 나는 또한 나에게 IntPtr
를 반환 Marshal.AllocHGlobal
로 버퍼를 할당 한 수 한 다음 나중에 무료로 Marshal.FreeGlobal
에 있지만이 경우에는 관리 코드에서 배열의 데이터를 사용할 필요가있다. 배열 포인터를 관리되는 코드에서 건드리지 않고 다른 관리되지 않는 함수에 전달하려고한다면 GCHandle이 활성화되어있는 동안 메모리가 가비지 컬렉터에 영향을주는 메모리에 잠겨 있습니다.).
"청소"를 사용하면 보안에 관심이 있음을 나타내지 만 실제로 메모리가 해제되었는지 여부를 알고 싶다고 생각합니다. 나 맞아? –
예, 현재 메모리를 확보하는 것이 더 중요합니다. – vrrathod
문서에서는 AllocHGlobal() 및 FreeHGlobal()이 Win32 LocalAlloc() 및 LocalFree() 함수를 둘러싼 래퍼 일 뿐이라고합니다. 같은 양의 allocator를 사용하고있는 한 괜찮을 것이다. – Luke