PtrToStringUni doesnt work in windows 10

守給你的承諾、 提交于 2021-01-29 14:12:54

问题


So i have been using urlmon.dll's help with getting the MIME type of files' data as suggested in This answer, and its been working fine in windows 7.

However, on windows 10 the same code generates System.AccessViolationException when trying to create a string from the mime pointer.

this is the problematic code:

uint mimeType;
FindMimeFromData(0, null, data, 256, null, 0, out mimeType, 0);
var mimePointer = new IntPtr(mimeType);
//Exception is thrown on the next line
var mime = Marshal.PtrToStringUni(mimePointer);

The code works fine on windows 7 and on the same files, however when running this on windows 10 i suddenly get Access Violation.

Did anyone else encounter this error ?


回答1:


uint mimeType;
FindMimeFromData(0, null, data, 256, null, 0, out mimeType, 0);
var mimePointer = new IntPtr(mimeType);

This is surely wrong at 64 bits... A IntPtr is 64 bits (it is a memory address)... How could a uint (a 32 bits) contain it?

And if we take a look at the pinvoke site the signature should be:

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
static extern int FindMimeFromData(IntPtr pBC,
    [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,
    [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1, SizeParamIndex=3)] 
    byte[] pBuffer,
    int cbSize,
    [MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed,
    int dwMimeFlags,
    out IntPtr ppwzMimeOut,
    int dwReserved);

very important while the documentation of the method is very poor on msdn, calling FindMimeFromData will cause a memory leak: you have to free the ppwzMimeOut you receive... The problem is that it isn't clear how: here it is suggested to use CoTaskMemFree, that is Marshal.FreeCoTaskMem. I'll say that it is right, tested with:

byte[] bytes = File.ReadAllBytes("someimage.jpg");

while (true)
{
    IntPtr ptr1;
    int success1 = FindMimeFromData(IntPtr.Zero, null, bytes, bytes.Length, null, 0, out ptr1, 0);
    Marshal.FreeCoTaskMem(ptr1);
}

If I remove the Marshal.FreeCoTaskMem and take a look with the TaskManager, the memory used by the process will go up quite quickly... If I restore the Marshal.FreeCoTaskMem, the memory will remain stable.



来源:https://stackoverflow.com/questions/51037460/ptrtostringuni-doesnt-work-in-windows-10

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!