开发者

DllImport PathCanonicalize on 64bit causes memory corruption

开发者 https://www.devze.com 2023-03-20 07:13 出处:网络
I am trying to use the function PathCanonicalize using DllImport (PInvoke) on a 64 bit .NET assembly, and it causes memory corruption leading to all kinds bad behaviors (crash, exceptions out of nowhe

I am trying to use the function PathCanonicalize using DllImport (PInvoke) on a 64 bit .NET assembly, and it causes memory corruption leading to all kinds bad behaviors (crash, exceptions out of nowhere, etc...). (For example : System.AccessViolationException: Attempted to read or write p开发者_StackOverflow社区rotected memory. This is often an indication that other memory is corrupt.)

    [DllImport("shlwapi", CharSet = CharSet.Auto, EntryPoint="PathCanonicalize", SetLastError = true)]
    private static extern bool PathCanonicalize( [Out] StringBuilder lpszDst,[In] string lpszSrc );

    public static string MyPathCanonicalize(string path)
    {
        StringBuilder builder = new StringBuilder();
        if (!PathCanonicalize(builder, path))
            return path;
        return builder.ToString();
    }

I saw in this thread that I should probably be using IntPtr instead of directly strings. Can anybody show me how to marshal those in the input and output strings in PathCanonicalize?

The prototype is:

BOOL PathCanonicalize(
  __out  LPTSTR lpszDst,
  __in   LPCTSTR lpszSrc
);


From the SDK documentation:

lpszDst
[out] A pointer to a string that receives the canonicalized path. You should set the size of this buffer to MAX_PATH to ensure that it is large enough to hold the returned string.

Which you didn't do. Fix:

    StringBuilder builder = new StringBuilder(260);


Per MSDN for PathCanonicalize (emphasis mine):

lpszDst [out]

Type: LPTSTR

A pointer to a string that receives the canonicalized path. You must set the size of this buffer to MAX_PATH to ensure that it is large enough to hold the returned string.

You'll need to initialize builder prior to the call:

public static readonly int MaxPath = 260;

public static string MyPathCanonicalize(string path)
{
    StringBuilder builder = new StringBuilder(MaxPath);
    if (!PathCanonicalize(builder, path))
        return path;
    return builder.ToString();
}

Also, note there is no [Out] on lpszDst, this is because the called method is not returning you a pointer, rather you're giving it a pointer to memory to write the canonicalized path. (disregard, it appears to handle it fine with or without the [Out])

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号