2012-06-18 53 views
15

我正在使用一個具有StringHandle字段的類,它是一個IntPtr值,它表示在C++中使用 LPCWSTR使IntPtr在C#.NET中指向字符串值

internal IntPtr StringHandle; // LPCWSTR 

現在說我有一個字符串:string x = "abcdefg"

我如何使用String把手指向字符串的開始,使之像C++ LPCWSTR?

+0

你爲什麼想這樣做? –

+0

我正在使用只存在於本機代碼(C++)中的接口,因此我使用.NET中的Interops。然而,有StringHandle的類不是我的,我不想改變。 –

+6

因爲這就是他與之合作的圖書館所期望的。並非所有的東西都有爲它構建的.NET包裝器,即使在框架內,當你處理諸如低級別Windows消息之類的事情時,Marshal類可以得到很好的使用。 – KeithS

回答

24

您需要將字符串首先複製到非託管內存中,然後從那個位置IntPtr。你可以這樣做:

IntPtr strPtr = Marshal.StringToHGlobalUni(x); 

還,您需要確保以釋放非託管內存:

Marshal.FreeHGlobal(strPtr); 

這是最好的做這一切在try /最後。

+0

我實際上需要這一個Marshal.StringToCoTaskMemUni,因爲我使用的是COM,但是非常感謝 –

7

託管字符串在垃圾收集器壓縮堆時在內存中移動。所以他們沒有一個穩定的地址,不能直接投射到LPCWSTR。您需要使用GCHandle.Alloc()來固定字符串以使用GCHandle.AddrOfPinnedObject,或者使用Marshal.StringToHGlobalUni()將其複製到非託管內存中。

如果地址需要穩定一段時間,強烈希望複製。

+0

對'string'的'AddrOfPinnedObject'是否給你一個指向字符數據的指針(問題中提到的'LPCWSTR')? (根據http://www.drdobbs.com/pinning-in-managed-c/184403869:是) –