DllImport PathCanonicalize on 64bit causes memory corruption
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 (disregard, it appears to handle it fine with or without the [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.[Out]
)
精彩评论