2011-06-17 51 views
3

當我從.Net代碼中多次執行CryptFindLocalizedName時,它返回無效信息。第一次調用是準確的,但使用相同字符串的任何子序列調用都會返回錯誤的數據。我不是在C#中使用Win32 api的專家,所以我可能做錯了什麼。CryptFindLocalizedName在多個調用中返回無效字符串

這裏是我的代碼...

[DllImport("cryp32.dll", CharSet = CharSet.Auto] 
public static extern string CryptFindLocalizedName(
    [In] string pwszCryptName 
); 

public static void Test() 
{ 
    Console.WriteLine(CryptFindLocalizedName("My")); // Returns "Personal" 
    Console.WriteLine(CryptFindLocalizedName("My")); // Returns "<weirdchar>ersonal" 
} 

我試圖友好名稱返回證書存儲。

我在做什麼錯?

回答

2

問題可能是編組人員正在做的事情不應該與返回值。 MSDN文檔指出:

返回的指針不能被釋放。

但是C#marshaller並不知道。相反,您需要控制返回值的編組。

[DllImport("cryp32.dll", CharSet = CharSet.Auto] 
public static extern IntPtr CryptFindLocalizedName(
    string pwszCryptName 
); 

public static void Test() 
{ 
    IntPtr retval = CryptFindLocalizedName("My"); 
    string name = Marshal.PtrToStringUni(retval); 
} 

爲了簡單起見,我忽略了錯誤處理,但這是你問題的本質。

PtrToStringUni狀態的文檔:當混合託管和非託管代碼

PtrToStringUni是對自定義編組或用途。由於此方法創建了非託管字符串內容的副本,因此必須根據需要釋放原始字符串。

換句話說,它不會從CryptFindLocalizedName中釋放返回值,這正是您在這種情況下想要的。

+0

解決了!還有一個很好的解釋來幫助像我這樣的新秀。謝謝。 – GeneS