Win32 Filewrite 구현
-
12-09-2019 - |
문제
[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#에서 파일 쓰기를 달성하는 더 좋은 방법이 있습니다.