2011-07-13 47 views
1

我想在64位.NET程序集上使用函數PathCanonicalize使用DllImport(PInvoke),它會導致內存損壞導致各種不良行爲(崩潰,等等...)。 (例如:System.AccessViolationException:試圖讀取或寫入保護內存這通常是指示其他內存已損壞。)在64位DllImport PathCanonicalize導致內存損壞

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

回答

5

從SDK文檔:

lpszDst
[out]一個指針到接收 規範化路徑的字符串。 您應該將此緩衝區的大小設置爲MAX_PATH 以確保它足夠大以容納返回的字符串。

你沒有做的。修復:

StringBuilder builder = new StringBuilder(260); 
+0

謝謝,它修復了它! – decasteljau

3

每MSDN爲PathCanonicalize(重點煤礦):

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]細處理它)

+0

+1爲什麼把[In]放在'lpszSrc'上?這隱含地是由於編組慣例。 –

+0

複製粘貼失敗,無論如何我已經將其刪除,因爲它似乎與'[Out]'屬性一起工作。 – user7116

+0

'[in]'和'[out]'註釋是針對C/C++頭文件的,您不應該將它們複製到C#中。 –