64位上的DllImport PathCanonicalize导致内存损坏

本文关键字:内存 损坏 PathCanonicalize DllImport 64位 | 更新日期: 2023-09-27 18:01:54

我正试图在64位.NET程序集上使用DllImport(PInvoke(来使用函数PathCanonicalize,它会导致内存损坏,从而导致各种不良行为(崩溃、意外异常等(。(例如:System.AccessViolationException:试图读取或写入受保护的内存。这通常表明其他内存已损坏。(

    [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();
    }

我在这个线程中看到,我可能应该使用IntPtr,而不是直接使用字符串。有人能告诉我如何在PathCanonicalize中封送输入和输出字符串中的那些吗?

原型是:

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

64位上的DllImport PathCanonicalize导致内存损坏

来自SDK文档:

lpszDst
[out]指向接收规范化的路径您应该将此缓冲区的大小设置为MAX_PATH以确保它足够大,可以容纳返回的字符串。

你没有这么做。修复:

    StringBuilder builder = new StringBuilder(260);

根据MSDN for PathCanonicalize(emphasis mine(:

lpszDst[out]

类型:LPTSTR

指向接收规范化路径的字符串的指针必须将此缓冲区的大小设置为MAX_PATH,以确保其足够大,可以容纳返回的字符串

您需要在调用之前初始化builder

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();
}

此外,请注意,lpszDst上没有[Out],这是因为被调用的方法不会向您返回指针,而是向它提供一个指向内存的指针来写入规范化路径(忽略,无论是否使用[Out],似乎都能很好地处理它(

相关文章: