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

时间:2011-07-13 20:04:37

标签: c# 64-bit pinvoke

我试图在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();
    }

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

原型是:

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

2 个答案:

答案 0 :(得分:5)

从SDK文档:

  

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

你没做过。修正:

    StringBuilder builder = new StringBuilder(260);

答案 1 :(得分:3)

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

另外,请注意[Out]上没有lpszDst,这是因为被调用的方法没有返回指针,而是给它一个指向内存的指针来写入规范化路径。 (无论是否使用[Out]似乎处理得很好)