マルチバイト配列をファイルに直接書き込み/読み取りしようとしていますが、PInvoke WriteFile/ReadFileを使用するように提案されました。
基本的に、私の読み取りコードは次のようになります。
[DllImport("kernel32.dll", SetLastError = true)]
static extern unsafe int ReadFile(IntPtr handle, IntPtr bytes, uint numBytesToRead,
IntPtr numBytesRead, System.Threading.NativeOverlapped* overlapped);
..<cut>..
byte[,,] mb = new byte[1024,1024,1024];
fixed(byte * fb = mb)
{
FileStream fs = new FileStream(@"E:\SHARED\TEMP", FileMode.Open);
int bytesread = 0;
ReadFile(fs.SafeFileHandle.DangerousGetHandle(), (IntPtr)fb, Convert.ToUInt32(mb.Length), new IntPtr(bytesread), null);
fs.Close();
}
このコードはAccessViolationExceptionをスローします。ただし、次のコードはそうではありません。
[DllImport("kernel32.dll", SetLastError = true)]
static extern unsafe int ReadFile(IntPtr handle, IntPtr bytes, uint numBytesToRead,
ref int numBytesRead, System.Threading.NativeOverlapped* overlapped);
..<cut>..
byte[,,] mb = new byte[1024,1024,1024];
fixed(byte * fb = mb)
{
FileStream fs = new FileStream(@"E:\SHARED\TEMP", FileMode.Open);
int bytesread = 0;
ReadFile(fs.SafeFileHandle.DangerousGetHandle(), (IntPtr)fb, Convert.ToUInt32(mb.Length), ref bytesread, null);
fs.Close();
}
違いは、numBytesReadをIntPtrではなくrefintとして宣言することです。
ただし、「IntPtrをintに変換する方法」という質問に対する答えが見つかるところはどこでも、次のようになります。
int x = 0;
IntPtr ptrtox = new IntPtr(x)
だから、私は何が間違っているのですか?なぜアクセス違反なのですか?