我正在使用一個具有StringHandle
字段的類,它是一個IntPtr
值,它表示在C++中使用 LPCWSTR
。使IntPtr在C#.NET中指向字符串值
internal IntPtr StringHandle; // LPCWSTR
現在說我有一個字符串:string x = "abcdefg"
我如何使用String把手指向字符串的開始,使之像C++ LPCWSTR?
我正在使用一個具有StringHandle
字段的類,它是一個IntPtr
值,它表示在C++中使用 LPCWSTR
。使IntPtr在C#.NET中指向字符串值
internal IntPtr StringHandle; // LPCWSTR
現在說我有一個字符串:string x = "abcdefg"
我如何使用String把手指向字符串的開始,使之像C++ LPCWSTR?
您需要將字符串首先複製到非託管內存中,然後從那個位置IntPtr
。你可以這樣做:
IntPtr strPtr = Marshal.StringToHGlobalUni(x);
還,您需要確保以釋放非託管內存:
Marshal.FreeHGlobal(strPtr);
這是最好的做這一切在try /最後。
我實際上需要這一個Marshal.StringToCoTaskMemUni,因爲我使用的是COM,但是非常感謝 –
你想用的StringTo *方法之一在Marshal
類
託管字符串在垃圾收集器壓縮堆時在內存中移動。所以他們沒有一個穩定的地址,不能直接投射到LPCWSTR。您需要使用GCHandle.Alloc()來固定字符串以使用GCHandle.AddrOfPinnedObject,或者使用Marshal.StringToHGlobalUni()將其複製到非託管內存中。
如果地址需要穩定一段時間,強烈希望複製。
對'string'的'AddrOfPinnedObject'是否給你一個指向字符數據的指針(問題中提到的'LPCWSTR')? (根據http://www.drdobbs.com/pinning-in-managed-c/184403869:是) –
你爲什麼想這樣做? –
我正在使用只存在於本機代碼(C++)中的接口,因此我使用.NET中的Interops。然而,有StringHandle的類不是我的,我不想改變。 –
因爲這就是他與之合作的圖書館所期望的。並非所有的東西都有爲它構建的.NET包裝器,即使在框架內,當你處理諸如低級別Windows消息之類的事情時,Marshal類可以得到很好的使用。 – KeithS