我试图在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
);
答案 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]
似乎处理得很好)