C #에서 byte []에서 IntPtr을 얻는 방법 변수 byte[]를 사용하는

C #에서 매개 변수 byte[]를 사용하는 메서드에 a 를 전달하고 싶습니다. IntPtr가능합니까?



답변

배열에 IntPtr을 가져 오는 것에 대해 확실하지 않지만 Mashal.Copy를 사용하여 관리되지 않는 코드와 함께 사용할 데이터를 복사 할 수 있습니다.

IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length);
// Call unmanaged code
Marshal.FreeHGlobal(unmanagedPointer);

또는 하나의 속성으로 구조체를 선언 한 다음 Marshal.PtrToStructure를 사용할 수 있지만 여전히 관리되지 않는 메모리를 할당해야합니다.

편집 : 또한 Tyalis가 지적했듯이 안전하지 않은 코드가 옵션 인 경우 고정 을 사용할 수도 있습니다


답변

또 다른 방법,

GCHandle pinnedArray = GCHandle.Alloc(byteArray, GCHandleType.Pinned);
IntPtr pointer = pinnedArray.AddrOfPinnedObject();
// Do your stuff...
pinnedArray.Free();

답변

이것은 작동하지만 안전하지 않은 상황에서 사용해야합니다.

byte[] buffer = new byte[255];
fixed (byte* p = buffer)
{
    IntPtr ptr = (IntPtr)p;
    // do you stuff here
}

고정 블록에서 포인터를 사용해야합니다. gc는 더 이상 고정 블록에 있지 않으면 객체를 이동할 수 있습니다.


답변

Marshal.UnsafeAddrOfPinnedArrayElement(array, 0)배열에 대한 메모리 포인터를 얻는 데 사용할 수 있습니다 .


답변

다음은 @ user65157의 답변을 변형 한 것입니다 (BTW의 경우 +1).

고정 된 개체에 대한 IDisposable 래퍼를 만들었습니다.

class AutoPinner : IDisposable
{
   GCHandle _pinnedArray;
   public AutoPinner(Object obj)
   {
      _pinnedArray = GCHandle.Alloc(obj, GCHandleType.Pinned);
   }
   public static implicit operator IntPtr(AutoPinner ap)
   {
      return ap._pinnedArray.AddrOfPinnedObject();
   }
   public void Dispose()
   {
      _pinnedArray.Free();
   }
}

다음과 같이 사용하십시오 :

using (AutoPinner ap = new AutoPinner(MyManagedObject))
{
   UnmanagedIntPtr = ap;  // Use the operator to retrieve the IntPtr
   //do your stuff
}

나는 이것이 Free () 호출하는 것을 잊지 않는 좋은 방법이라는 것을 알았습니다. 🙂


답변

원수. 복사는 작동하지만 속도가 느립니다. for 루프에서 바이트를 복사하는 것이 더 빠릅니다. 더 빠른 방법은 바이트 배열을 ulong 배열로 캐스트하고 바이트 배열에 맞는만큼 ulong을 복사 한 다음 남은 7 바이트 (8 바이트가 정렬되지 않은 트레일)를 복사하는 것입니다. Tyalis의 답변에서 위에서 제안한 것처럼 고정 배열로 바이트 배열을 고정하는 것이 가장 빠릅니다.


답변

IntPtr GetIntPtr(Byte[] byteBuf)
{
    IntPtr ptr = Marshal.AllocHGlobal(byteBuf.Length);
    for (int i = 0; i < byteBuf.Length; i++)
    {
       Marshal.WriteByte(ptr, i, byteBuf[i]);
    }
    return ptr;
}