[英]Do I need to call Marshal.DestroyStructure when marshalling structures containing ByValTStr strings
我正在為從 C#/.NET 到非托管 DLL 的互操作做一些手動封送處理。
考慮以下結構:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct LockInfo
{
ushort lockVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string lockName;
}
我將其編組為非托管 memory:
var lockInfo = new LockInfo();
var lockInfoPtr = Marshal.AllocHGlobal(Marshal.SizeOf(lockInfo));
Marshal.StructureToPtr(lockInfo, lockInfoPtr, false);
完成后,是否需要在lockInfoPtr
上調用Marshal.DestroyStructure
?
我知道需要調用Marshal.FreeHGlobal
,但在此之前,在這種情況下是否真的需要Marshal.DestroyStructure
?
我發現很難理解微軟的相關文檔。 谷歌搜索沒有幫助,可能是因為我還不太了解編組(但我正在學習)。
類似的問題...
我已經審查了類似的問題“ Marshal.DestroyStructure vs Marshal.FreeHGlobal in.Net ”,但是這個問題沒有解決結構應該包含的內容問題,這需要使用DestroyStructure
。 我有限的理解是DestroyStructure
並不總是需要調用,只有當結構包含某些類型的字段時。 在我的情況下,我不確定一個被編組為 ByValTStr 的字符串是否需要使用DestroyStructure
。
編組是復雜的東西,一個完整的答案可能會寫滿一本書的一整章,這在這里當然不合適。 所以,簡而言之:
通常,當從托管代碼調用本機函數時,.NET 將字符串和 arrays 編組為本機BSTR字符串和SafeArray arrays。
為此,封送拆收器分別調用SysAllocString
和SafeArrayCreate
。
在某些時候,當不再需要這些本機端字符串和 arrays 時,編組器將分別調用SysFreeString
和SafeArrayDestroy
來釋放 memory。
如果您接管 .NET 的自動封送處理,並調用Marshal.StructureToPtr
等方法來手動封送結構,您將負責釋放/銷毀那些本機端 BSTR 和 SafeArrays。 這正是Marshal.DestroyStructure
的用途。
然而...
通過將[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
屬性添加到您的字符串字段,您指示編組器不要將字符串編組為 BSTR 字符串,而是在本機端分配一個固定長度的字符數組結構本身。
在這種情況下,無需調用Marshal.DestroyStructure
,因為沒有要釋放的 BSTR 字符串。 當然,您仍然需要致電Marshal.FreeHGlobal
,我知道您已經意識到這一點。
感謝@SimonMourier的評論,讓一切都得到了點擊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.