문제

[DllImport("kernel32.dll", SetLastError=true)]
    public static extern unsafe bool WriteFile(IntPtr hFile, void* lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, IntPtr lpOverlapped);

서명으로 쓰기 (..) 메소드를 통해 이것을 구현하고 있습니다.

Write(IntPtr handleFile, void* bufferData, uint length){
    void* buffer = bufferData
    while (length > 0)
    {
      uint wrtn;
      if (!WriteFile(handle, buffer, len, out wrtn, IntPtr.Zero))
      {
         // Do some error handling
      }
      // THIS DOESNT WORK!
      // I want to move along the buffer to be able to write its remainder...
      // I tried many variations of this as well, but it seems even '+' is not valid  for a void*
      buffer += wrtn;
      len -= wrtn;
    }
}

내가 보면서 배운대로 이것 (읽기 상대의 사용에 대해 논의) 버퍼의 쓰기/읽기가 한 번에 통과되지 않을 수 있으므로 내 코드에서 while 루프를 구현해야합니다. 문제가 시작되는 곳입니다.

C# 메소드 서명을 void*를 수락하도록 유지하려면 바이트*가 버퍼의 매개 변수로 허용되는 링크 된 읽기 예제와 달리.

이것은 WriteFile의 한 번의 패스 후에는 아직 쓰여지지 않은 버퍼의 시작 부분으로 공허*를 움직여야한다는 것을 의미합니다. 나는 바이트의 수를 보유한 uint로 void*를 증가 시켜서 이것을 할 수는 없습니다 ... void*는 미리 결정된 크기가없고 증분이 불가능하지만 어떻게 무엇을 달성 해야하는지 궁금합니다. 나는하려고한다.

도움이 되었습니까?

해결책

캐스팅 할 수 있어야합니다 buffer a byte* 그런 다음 증가합니다. 빈 공간 포인터에는 크기가 연결되어 있지 않으므로 원한다면 이동하다 모든 방향으로 특정 바이트가 다른 유형의 포인터 (해당 물질에 대한 모든 유형)로 캐스팅 한 다음 포인터 산술에서 캐스트 된 유형의 크기를 사용하여 다음과 같이 사용할 수 있습니다.

buffer = (void *)((byte*)buffer + wrtn);

위의 선은 캐스트입니다 buffer 바이트 포인터에 wrtn 바이트 수와 새 포인터를 공허*로 다시 캐스팅합니다. 물론, 캐스팅 byte* 임의의 포인터 산술을 수행하려는 경우 명백한 선택입니다.

또 다른 가능성은 치료하는 것입니다 buffer A로 byte* 모두와 함께 캐스팅됩니다 void* 당신이 그것을 전달할 때 WriteFile

Write(IntPtr handleFile, void* bufferData, uint length)
{
    byte* buffer = (byte*)bufferData;
    while (length > 0)
    {
      uint wrtn;
      if (!WriteFile(handle, (void*)buffer, len, out wrtn, IntPtr.Zero))
      {
         // Do some error handling
      }
      buffer += wrtn;
      len -= wrtn;
    }
}

그리고 마지막 제안으로, 나는 서명을 바꾸는 것을 고려할 것입니다. Write 모두 사용하기 위해 byte* 대신에 void* C# 및 A의 다른 발신자와 더 호환되기 때문에 byte* 이 경우 더 의미가 있습니다. 캐스트 할 수 있기 때문에 쓰기 파일 네이티브 API의 서명과 일치하는 것에 대해 걱정할 필요가 없습니다. byte* 위에 표시된대로 a void* 통과 할 때.

Write(IntPtr handleFile, byte* bufferData, uint length)
{
    while (length > 0)
    {
      uint wrtn;
      if (!WriteFile(handle, (void*)bufferData, len, out wrtn, IntPtr.Zero))
      {
         // Do some error handling
      }
      bufferData+= wrtn;
      len -= wrtn;
    }
}

아아, 나는 논평자 중 한 명과 동의해야한다. 왜 이런 짓을하는? 많은 스트림 지향 클래스를 사용하여 C#에서 파일 쓰기를 달성하는 더 좋은 방법이 있습니다.

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