【问题标题】:DllImport PathCanonicalize on 64bit causes memory corruption64 位上的 DllImport PathCanonicalize 导致内存损坏
【发布时间】:2011-07-13 20:04:37
【问题描述】:

我正在尝试在 64 位 .NET 程序集上使用 DllImport (PInvoke) 的 PathCanonicalize 函数,它会导致内存损坏,从而导致各种不良行为(崩溃、突然出现的异常等)。 (例如:System.AccessViolationException: Attempted to read or write protected memory。这通常表明其他内存已损坏。)

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

我在this thread 中看到我可能应该使用 IntPtr 而不是直接使用字符串。谁能告诉我如何在 PathCanonicalize 的输入和输出字符串中编组?

原型是:

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

【问题讨论】:

    标签: c# 64-bit pinvoke


    【解决方案1】:

    来自 SDK 文档:

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

    你没有做的。修复:

        StringBuilder builder = new StringBuilder(260);
    

    【讨论】:

      【解决方案2】:

      PathCanonicalize 的每个 MSDN(强调我的):

      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],它似乎都能很好地处理它)

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多