簡體   English   中英

編組包含 ByValTStr 字符串的結構時是否需要調用 Marshal.DestroyStructure

[英]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。

為此,封送拆收器分別調用SysAllocStringSafeArrayCreate

在某些時候,當不再需要這些本機端字符串和 arrays 時,編組器將分別調用SysFreeStringSafeArrayDestroy來釋放 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM