C#中Marshal 类的内存操作的一般功能概述
Marshal 類的內(nèi)存操作的一般功能
Marshal類
提供了一個(gè)方法集,這些方法用于分配非托管內(nèi)存、復(fù)制非托管內(nèi)存塊、將托管類型轉(zhuǎn)換為非托管類型,此外還提供了在與非托管代碼交互時(shí)使用的其他雜項(xiàng)方法。
命名空間:System.Runtime.InteropServices
?
Marshal 類中定義的 static 方法對(duì)于處理非托管代碼至關(guān)重要。此類中定義的大多數(shù)方法通常由需要在托管和非托管編程模型之間提供橋梁的開發(fā)人員使用。
例如,StringToHGlobalAnsi 方法將 ANSI 字符從指定的字符串(在托管堆中)復(fù)制到非托管堆中的緩沖區(qū)。該方法還分配大小正確的目標(biāo)堆。
?
? 公共方法
| 方法名稱 | 說明 |
| AddRef?? | 遞增指定接口上的引用計(jì)數(shù)。 |
| AllocCoTaskMem?? | 從 COM 任務(wù)內(nèi)存分配器分配指定大小的內(nèi)存塊。 |
| AllocHGlobal?? | 使用 LocalAlloc?分配內(nèi)存塊。 |
| BindToMoniker?? | 獲取由指定的名字對(duì)象標(biāo)識(shí)的接口指針。 |
| ChangeWrapperHandleStrength?? | 在 COM 可調(diào)用包裝 (CCW) 句柄包含的對(duì)象上更改它的強(qiáng)度。 |
| Copy?? | 將數(shù)據(jù)從托管數(shù)組復(fù)制到非托管內(nèi)存指針,或從非托管內(nèi)存指針復(fù)制到托管數(shù)組。 |
| CreateAggregatedObject?? | 聚合托管對(duì)象和指定的 ? COM 對(duì)象。 |
| CreateWrapperOfType?? | 在指定類型的對(duì)象中包裝指定的 COM 對(duì)象。 |
| DestroyStructure?? | 釋放指定的非托管內(nèi)存塊所指向的所有子結(jié)構(gòu)。 |
| Equals? ? | 。 確定兩個(gè) ??Object?? 實(shí)例是否相等。 (從?Object?? 繼承。) |
| FinalReleaseComObject?? | 通過將提供的運(yùn)行庫可調(diào)用包裝 (RCW) 的引用計(jì)數(shù)設(shè)置為 0,釋放對(duì) RCW 的所有引用。 |
| FreeBSTR?? | 使用 ? SysFreeString 釋放 BSTR。 |
| FreeCoTaskMem?? | 釋放由非托管 COM 任務(wù)內(nèi)存分配器使用?Marshal.AllocCoTaskMem?? 分配的內(nèi)存塊。 |
| FreeHGlobal?? | 釋放以前使用?AllocHGlobal???從進(jìn)程的非托管內(nèi)存中分配的內(nèi)存。 |
| GenerateGuidForType?? | 返回指定類型的全局唯一標(biāo)識(shí)符 (GUID),或使用類型庫導(dǎo)出程序 (TlbExp.exe) 所用的算法生成 GUID。 |
| GenerateProgIdForType?? | 返回指定類型的編程標(biāo)識(shí)符 ? (ProgID)。 |
| GetActiveObject?? | 從運(yùn)行對(duì)象表 (ROT) ? 獲取指定對(duì)象的運(yùn)行實(shí)例。 ? |
| GetComInterfaceForObject?? | 返回一個(gè)接口指針,該接口指針表示對(duì)象的指定接口。 |
| GetComInterfaceForObjectInContext?? | 返回一個(gè)接口指針,該指針表示對(duì)象的指定接口(如果調(diào)用方與對(duì)象在同一上下文中)。 |
| GetComObjectData?? | 從指定的 COM 對(duì)象獲取指定鍵所引用的數(shù)據(jù)。 |
| GetComSlotForMethodInfo?? | 獲取指定的?System.Reflection.MemberInfo?? 在向 COM 公開時(shí)的虛函數(shù)表 (VTBL) 槽。 |
| GetDelegateForFunctionPointer?? | 將非托管函數(shù)指針轉(zhuǎn)換為委托。 |
| GetEndComSlot?? | 獲取在向 COM 公開時(shí)某個(gè)類型的虛函數(shù)表 (VTBL) 中的最后一個(gè)槽。 |
| GetExceptionCode?? | 檢索標(biāo)識(shí)所發(fā)生異常的類型的代碼。 |
| GetExceptionForHR?? | 。 將 HRESULT 錯(cuò)誤代碼轉(zhuǎn)換為對(duì)應(yīng)的?Exception?? 對(duì)象。 |
| GetExceptionPointers?? | 檢索與計(jì)算機(jī)無關(guān)的異常描述以及有關(guān)異常發(fā)生時(shí)線程的狀態(tài)信息。 |
| GetFunctionPointerForDelegate?? | 將委托轉(zhuǎn)換為可從非托管代碼調(diào)用的函數(shù)指針。 |
| GetHashCode? ? | 用作特定類型的哈希函數(shù)。GetHashCode?? 適合在哈希算法和數(shù)據(jù)結(jié)構(gòu)(如哈希表)中使用。 (從?Object?? 繼承。) |
| GetHINSTANCE?? | 返回指定模塊的實(shí)例句柄 ? (HINSTANCE)。 |
| GetHRForException?? | 將指定異常轉(zhuǎn)換為 ? HRESULT。 |
| GetHRForLastWin32Error?? | 返回 HRESULT,它與使用?Marshal?? 執(zhí)行的 Win32 代碼引起的最后一個(gè)錯(cuò)誤相對(duì)應(yīng)。 |
| GetIDispatchForObject?? | 從托管對(duì)象返回一個(gè) ? IDispatch 接口。 |
| GetIDispatchForObjectInContext?? | 如果調(diào)用方與托管對(duì)象在同一上下文中,則從該對(duì)象返回一個(gè) IDispatch 接口指針。 |
| GetITypeInfoForType?? | 從托管類型返回一個(gè) ? ITypeInfo 接口。 |
| GetIUnknownForObject?? | 從托管對(duì)象返回一個(gè) ? IUnknown 接口。 |
| GetIUnknownForObjectInContext?? | 如果調(diào)用方與托管對(duì)象在同一上下文中,則從該對(duì)象返回一個(gè) IUnknown 接口。 |
| GetLastWin32Error?? | 返回由上一個(gè)非托管函數(shù)返回的錯(cuò)誤代碼,該函數(shù)是使用設(shè)置了?DllImportAttribute.SetLastError?? 標(biāo)志的平臺(tái)調(diào)用來調(diào)用的。 ? |
| GetManagedThunkForUnmanagedMethodPtr?? | 獲取指向 thunk 的指針,該 thunk 封送從托管代碼到非托管代碼的調(diào)用。 |
| GetMethodInfoForComSlot?? | 檢索指定的虛函數(shù)表 ? (VTBL) 槽的?MethodInfo。 |
| GetNativeVariantForObject?? | 將對(duì)象轉(zhuǎn)換為 COM ? VARIANT。 |
| GetObjectForIUnknown?? | 返回通過指向 COM 對(duì)象的 IUnknown 接口的指針表示該對(duì)象的類型實(shí)例。 |
| GetObjectForNativeVariant?? | 將 COM ? VARIANT 轉(zhuǎn)換為對(duì)象。 |
| GetObjectsForNativeVariants?? | 將 COM ? VARIANT 數(shù)組轉(zhuǎn)換為對(duì)象數(shù)組。 |
| GetStartComSlot?? | 獲取虛函數(shù)表 ? (VTBL) 中第一個(gè)包含用戶定義的方法的槽。 |
| GetThreadFromFiberCookie?? | 將纖程 Cookie 轉(zhuǎn)換為相應(yīng)的?System.Threading.Thread?? 實(shí)例。 |
| GetType? ? | 獲取當(dāng)前實(shí)例的?Type。 (從?Object?? 繼承。) |
| GetTypedObjectForIUnknown?? | 返回表示 COM 對(duì)象的指定類型的托管對(duì)象。 |
| GetTypeForITypeInfo?? | 將 ITypeInfo 轉(zhuǎn)換為托管 Type 對(duì)象。 |
| GetTypeInfoName?? | 。 檢索由 ITypeInfo 表示的類型的名稱。 |
| GetTypeLibGuid?? | 。 檢索類型庫的庫標(biāo)識(shí)符 (LIBID)。 |
| GetTypeLibGuidForAssembly?? | 檢索從指定程序集導(dǎo)出類型庫時(shí)分配給該類型庫的庫標(biāo)識(shí)符 (LIBID)。 |
| GetTypeLibLcid?? | 。 檢索類型庫的 LCID。 |
| GetTypeLibName?? | 。 檢索類型庫的名稱。 |
| GetTypeLibVersionForAssembly?? | 檢索將從指定程序集導(dǎo)出的類型庫的版本號(hào)。 |
| GetUniqueObjectForIUnknown?? | 為給定的 ? IUnknown 創(chuàng)建唯一的運(yùn)行庫可調(diào)用包裝 (RCW) 對(duì)象。 |
| GetUnmanagedThunkForManagedMethodPtr?? | 獲取指向 thunk 的指針,該 thunk 封送從非托管代碼到托管代碼的調(diào)用。 |
| IsComObject?? | 指示指定對(duì)象是否表示 ? COM 對(duì)象。 |
| IsTypeVisibleFromCom?? | 指示類型對(duì) COM 客戶端是否可見。 |
| NumParamBytes?? | 計(jì)算在非托管內(nèi)存中保存指定方法的參數(shù)所需要的字節(jié)數(shù)。 |
| OffsetOf?? | 返回托管類的非托管形式的字段偏移量。 |
| Prelink?? | 在不調(diào)用方法的情況下執(zhí)行一次性方法設(shè)置任務(wù)。 |
| PrelinkAll?? | 對(duì)類上的所有方法執(zhí)行預(yù)鏈接檢查。 |
| PtrToStringAnsi?? | ?分配托管?String?? 并向其復(fù)制所有或部分非托管 ANSI 字符串。 |
| PtrToStringAuto?? | ?分配托管 String,并從非托管字符串向其復(fù)制指定數(shù)目的字符。 |
| PtrToStringBSTR?? | 分配托管 String,并向其復(fù)制存儲(chǔ)在非托管內(nèi)存中的 BSTR 字符串。 |
| PtrToStringUni?? | ?分配托管 String,并從非托管 Unicode 字符串向其復(fù)制指定數(shù)目的字符。 |
| PtrToStructure?? | 將數(shù)據(jù)從非托管內(nèi)存塊封送到托管對(duì)象。 |
| QueryInterface?? | 從 COM 對(duì)象請(qǐng)求指向指定接口的指針。 |
| ReadByte?? | ?從非托管指針讀取單個(gè)字節(jié)。 |
| ReadInt16?? | ?從非托管內(nèi)存中讀取一個(gè) 16 位有符號(hào)整數(shù)。 |
| ReadInt32?? | ?從非托管內(nèi)存中讀取一個(gè) 32 位有符號(hào)整數(shù)。 |
| ReadInt64?? | ?從非托管內(nèi)存中讀取一個(gè) 64 位有符號(hào)整數(shù)。 |
| ReadIntPtr?? | ?從非托管內(nèi)存中讀取處理器本機(jī)大小的整數(shù)。 |
| ReAllocCoTaskMem?? | 調(diào)整以前用 ? AllocCoTaskMem 分配的內(nèi)存塊的大小。 |
| ReAllocHGlobal?? | 調(diào)整以前用 ? AllocHGlobal 分配的內(nèi)存塊的大小。 |
| ReferenceEquals? ? | 確定指定的 Object ? 實(shí)例是否是相同的實(shí)例。 (從?Object?? 繼承。) |
| Release?? | 遞減指定接口上的引用計(jì)數(shù)。 |
| ReleaseComObject?? | 遞減所提供的運(yùn)行庫可調(diào)用包裝的引用計(jì)數(shù)。 |
| ReleaseThreadCache?? | 釋放線程緩存。 |
| SecureStringToBSTR?? | 分配 BSTR 并向其復(fù)制托管?SecureString?? 對(duì)象的內(nèi)容。 |
| SecureStringToCoTaskMemAnsi?? | 將托管 ? SecureString 對(duì)象的內(nèi)容復(fù)制到從非托管 ? COM 任務(wù)分配器分配的內(nèi)存塊。 ? |
| SecureStringToCoTaskMemUnicode?? | 將托管 ? SecureString 對(duì)象的內(nèi)容復(fù)制到從非托管 ? COM 任務(wù)分配器分配的內(nèi)存塊。 ? |
| SecureStringToGlobalAllocAnsi?? | 將托管 ? SecureString 中的內(nèi)容復(fù)制到非托管內(nèi)存,并在復(fù)制時(shí)轉(zhuǎn)換為 ANSI 格式。 |
| SecureStringToGlobalAllocUnicode?? | 向非托管內(nèi)存復(fù)制托管 ? SecureString 的內(nèi)容。 |
| SetComObjectData?? | 設(shè)置由指定 COM 對(duì)象中的指定鍵引用的數(shù)據(jù)。 |
| SizeOf?? | ?使用 Marshal?返回類的非托管大小(以字節(jié)為單位)。 |
| StringToBSTR?? | 分配 BSTR 并向其復(fù)制托管 String 的內(nèi)容。 |
| StringToCoTaskMemAnsi?? | 將托管 String 的內(nèi)容復(fù)制到從非托管 COM 任務(wù)分配器分配的內(nèi)存塊。 |
| StringToCoTaskMemAuto?? | 將托管 String 的內(nèi)容復(fù)制到從非托管 COM 任務(wù)分配器分配的內(nèi)存塊。 |
| StringToCoTaskMemUni?? | 將托管 String 的內(nèi)容復(fù)制到從非托管 COM 任務(wù)分配器分配的內(nèi)存塊。 |
| StringToHGlobalAnsi?? | 將托管 String 中的內(nèi)容復(fù)制到非托管內(nèi)存,并在復(fù)制時(shí)轉(zhuǎn)換為 ANSI 格式。 |
| StringToHGlobalAuto?? | 向非托管內(nèi)存復(fù)制托管 ? String 的內(nèi)容,并在需要時(shí)轉(zhuǎn)換為 ? ANSI 格式。 |
| StringToHGlobalUni?? | 向非托管內(nèi)存復(fù)制托管 ? String 的內(nèi)容。 |
| StructureToPtr?? | 將數(shù)據(jù)從托管對(duì)象封送到非托管內(nèi)存塊。 |
| ThrowExceptionForHR?? | ?用特定的失敗 HRESULT 值引發(fā)異常。 |
| ToString? ? | 返回表示當(dāng)前 ? Object 的 String。 (從?Object?? 繼承。) |
| UnsafeAddrOfPinnedArrayElement?? | 獲取指定數(shù)組中指定索引處的元素的地址。 |
| WriteByte?? | ?將單個(gè)字節(jié)值寫入到非托管內(nèi)存。 |
| WriteInt16?? | ?將 16 位有符號(hào)整數(shù)寫入非托管內(nèi)存。 |
| WriteInt32?? | ?將 32 位有符號(hào)整數(shù)寫入非托管內(nèi)存。 |
| WriteInt64?? | ?將 64 位有符號(hào)整數(shù)寫入非托管內(nèi)存。 |
| WriteIntPtr?? | ?將一個(gè)處理器本機(jī)大小的整數(shù)值寫入非托管內(nèi)存。 |
| ZeroFreeBSTR?? | 釋放 BSTR 指針,該指針是使用?SecureStringToBSTR?? 方法分配的。 |
| ZeroFreeCoTaskMemAnsi?? | 釋放非托管字符串指針,該指針是使用?SecureStringToCoTaskMemAnsi?? 方法分配的。 |
| ZeroFreeCoTaskMemUnicode?? | 釋放非托管字符串指針,該指針是使用?SecureStringToCoTaskMemUnicode?? 方法分配的。 |
| ZeroFreeGlobalAllocAnsi?? | 釋放非托管字符串指針,該指針是使用?SecureStringToGlobalAllocAnsi?? 方法分配的。 |
| ZeroFreeGlobalAllocUnicode?? | 釋放非托管字符串指針,該指針是使用 SecureStringToCoTaskMemUnicode 方法分配的。 |
?
?簡(jiǎn)介
Marshal 類中有許多成員,但他們大多是公用事業(yè)援助COM代碼進(jìn)行互操作。
使用.NET,Visual Basic中有很大的權(quán)力,以至于處理在與 Windows 系統(tǒng)較低水平層次,并從外部庫的非托管代碼的工作。這權(quán)力是發(fā)現(xiàn)了三個(gè)新的工具:IntPtr的,NET的平臺(tái)相關(guān)的內(nèi)存地址代表性的GCHandle,從而你針和檢索的管理內(nèi)存堆的數(shù)據(jù)的地址; Marshal類的一站式。您的內(nèi)存分配,清理,和操作的需要。
如果您決定與VB.NET直接內(nèi)存操作,你需要了解的第一件事是IntPtr類型。
IntPtr 的是一個(gè)結(jié)構(gòu),它表示兩個(gè)地址和處理(大多數(shù)處理 Windows 的指針的指針)。
IntPtr 的實(shí)例也依賴于平臺(tái)的(或獨(dú)立,取決于你的觀點(diǎn))。在32位系統(tǒng),IntPtr 的是32位,而在64位系統(tǒng) IntPtr 的是64位。這樣做的好處是,你不需要更改或重新編譯你的代碼,或兩個(gè)平臺(tái)內(nèi)的任何.NET Framework的公開的方式與地址和處理工作的功能。
使用 IntPtr 類型,這種功能是封送到非托管代碼,僅僅作為內(nèi)部地址編號(hào),這意味著你可以通過一個(gè) IntPtr 類型的變量的任何非托管代碼的預(yù)計(jì)指針。因此,好消息是,雖然你不能在VB.NET中使用這樣的: 如void *?Dim MyPointer 這個(gè)工程精辟VB.NET:作為 IntPtr 的 DIM MyPointer
請(qǐng)注意,在Beta 1沒有IntPtr類型??相反,工作指針和處理使用 Integer 類型。
IntPtr 類型有 ToInt32 方法的地址轉(zhuǎn)換為一個(gè)整數(shù),但可以將導(dǎo)致在64位系統(tǒng)的溢出異常。 IntPtr 也有 ToInt64 方法,但你必須保持跟蹤的平臺(tái),如果你想要做的這些轉(zhuǎn)換。StrPtr()和 VarPtr()NBSP在 VB.NET 這兩個(gè)無證 VB 的6個(gè)功能變量的返回地址。相同的功能,可以在VB.NET的GCHandle類。
讓我們來看看如何放到一個(gè) IntPtr 變量的地址。您可以使用的 GCHandle 的類,它有一個(gè) AddrOfPinnedObject 的方法返回一個(gè)變量一個(gè)IntPtr。
您必須"針"的數(shù)據(jù),然后才可以得到這個(gè)地址。這可以防止不經(jīng)意間移動(dòng)數(shù)據(jù)的垃圾收集器,而你指的是原來的地址。這代碼引腳一個(gè)變量,其地址顯示在控制臺(tái)窗口,并釋放句柄:"昏暗的管理變量DIM MyString的字符串=阿德南塞繆爾? "針變量和創(chuàng)建"GC的處理實(shí)例昏暗的GH(MyString中,GCHandleType.Pinned)的GCHandle = GCHandle.Alloc "得到的變量的地址DIM AddrOfMyString作為IntPtr的= gh.AddrOfPinnedObject() Console.WriteLine(AddrOfMyString.ToString()) "自由的處理,并脫離"變量gh.Free()說明AllocHGlobal和AllocCoTaskMem
上的本機(jī)堆內(nèi)部使用GlobalAlloc函數(shù)分配內(nèi)存AllocHGlobal; AllocCoTaskMem,這是類似的,而是使用的COM內(nèi)存管理器(CoTaskMemAlloc來)。這兩個(gè)函數(shù)有一個(gè)參數(shù),分配的字節(jié)數(shù)。這兩個(gè)函數(shù)返回一個(gè)IntPtr,新分配的緩沖區(qū)的基地址。釋放內(nèi)存,您使用的FreeHGlobal或FreeCoTaskMem方法,取決于分配方法您使用。這些函數(shù)有一個(gè)參數(shù),新分配的緩沖區(qū)的分配函數(shù)返回地址。
使用WriteByte,WriteInt16,WriteInt32,或WriteInt64方法簡(jiǎn)單的數(shù)字?jǐn)?shù)據(jù)寫入到一個(gè)非托管的緩沖區(qū)。每個(gè)函數(shù)作為參數(shù)的寫操作的目的地址和數(shù)值你想要寫。這些功能也重載以允許可選的第三個(gè)參數(shù)指示從抵消所提供的地址,它可以是有用的,如果你試圖填充數(shù)組元素或結(jié)構(gòu)領(lǐng)域的內(nèi)存,例如:"分配一些內(nèi)存,并獲得它的地址DIM MyPointer的IntPtr = Marshal.AllocHGlobal(4) "寫入到該地址的數(shù)量255Marshal.WriteInt32(MyPointer,255) "一些更多的代碼(調(diào)用"例如的非托管代碼) "空閑內(nèi)存Marshal.FreeHGlobal(MyPointer)
您也可以使用提供的地址,而不是你自己分配的非托管代碼:D??IM MyPointer作為IntPtr的新的IntPtr([插入整數(shù)地址_??????????????? 從這里非托管代碼)] Marshal.WriteInt32(MyPointer,255)
反過來也有可能。你可以閱讀簡(jiǎn)單的數(shù)字?jǐn)?shù)據(jù),從一個(gè)IntPtr地址使用的readByte ReadInt16,ReadInt32,并ReadInt64方法:DIM MyInteger為整數(shù)= Marshal.ReadInt32(MyPointer)字符串函數(shù)
閱讀和寫作字符串相似,讀,寫簡(jiǎn)單的數(shù)字?jǐn)?shù)據(jù),有一個(gè)小的例外:你不先分配內(nèi)存,然后寫一個(gè)字符串。相反,在非托管內(nèi)存中創(chuàng)建一個(gè)字符串的行為分配的空間,并返回字符串的地址。寫有七個(gè)方法:StringToBSTR,StringToCoTaskMemAnsi,StringToCoTaskMemUni,StringToCoTaskMemAuto,StringToHGlobalAnsi,StringToHGlobalUni和StringToHGlobalAuto。 StringToCoTaskMemxxx功能字符串?dāng)?shù)據(jù)寫入到COM分配的內(nèi)存,而StringToHGlobalxxx功能寫入到本地的非托管堆。結(jié)束在ANSI的函數(shù)寫單字節(jié)ANSI字符串。結(jié)束在統(tǒng)一的函數(shù)寫雙字節(jié)的Unicode字符串。功能,自動(dòng)結(jié)束寫入ANSI或Unicode字符串,這取決于操作系統(tǒng):Windows 98和ME,NT為基礎(chǔ)的平臺(tái)(Windows NT 4.0中,2000年,和XP)的Unicode字符串的ANSI字符串。 StringToBSTR寫一個(gè)自動(dòng)化BSTR,這是類似于使用SysAllocString函數(shù)。這些函數(shù)接受一個(gè)字符串作為輸入?yún)?shù),并返回一個(gè)指針,得到的字符串:DIM MyStrPointer的IntPtr = Marshal.StringToHGlobalAuto(quot;您好Worldquot;)
四個(gè)讀的方法呢??PtrToStringAnsi,PtrToStringUni,PtrToStringAuto,PtrToStringBSTR??在一個(gè)給定的地址讀取數(shù)據(jù),并創(chuàng)建一個(gè)托管String對(duì)象,其中包含的字符的副本。 PtrToStringAnsi如果非托管字符串是ANSI,PtrToStringUni如果非托管字符串是Unicode,或PtrToStringBSTR如果非托管字符串是BSTR類型。 PtrToStringAuto假定非托管字符串是一個(gè)Windows 98或ME系統(tǒng)的ANSI和Unicode的Windows NT 4.0,2000或XP平臺(tái)上。 PtrToStringAuto實(shí)際上是調(diào)用PtrToStringAnsi或PtrToStringUni,取決于操作系統(tǒng)。每個(gè)函數(shù)重載接受一個(gè)可選的數(shù)字復(fù)制的字符。如果你沒有提供的字符數(shù),函數(shù)看起來為終止空字符:"復(fù)制整個(gè)字符串昏暗的MyString的字符串= Marshal.PtrToStringAuto(MyPointer)"復(fù)制前5個(gè)字符DIM MyString的字符串= Marshal.PtrToStringAuto(MyPointer,5)
拿著一個(gè)字符串要釋放非托管內(nèi)存緩沖區(qū),可以調(diào)用FreeHGlobal或FreeCoTaskMem成員。要免費(fèi)StringToBSTR創(chuàng)建一個(gè)BSTR,你叫FreeBSTR,這反過來又調(diào)用FreeSysString功能。 - ; StructureToPtr和PtrToStructure
你寫的非托管內(nèi)存結(jié)構(gòu)(用戶定義類型)使用的StructureToPtr方法。這種方法需要你有時(shí)間提前分配的內(nèi)存緩沖區(qū)。它有三個(gè)參數(shù):您要編寫的結(jié)構(gòu),內(nèi)存緩沖區(qū)的地址(IntPtr的),和一個(gè)刪除標(biāo)志。刪除標(biāo)志設(shè)置為True濕巾和釋放任何現(xiàn)有的數(shù)據(jù)從緩沖區(qū)。這是非常重要的,因?yàn)槟憧赡軙?huì)導(dǎo)致內(nèi)存泄漏不刪除現(xiàn)有的緩沖空間。例如,如果結(jié)構(gòu)的領(lǐng)域之一,是另一種結(jié)構(gòu)或字符串的引用,數(shù)據(jù)被外地引用不會(huì)被釋放,如果該參數(shù)設(shè)置為False。還要注意的是結(jié)構(gòu)復(fù)制到非托管內(nèi)存,使用特定的格式(你可以控制可選),和非托管的副本可能不像完全的托管表示。使用sizeof的方法來確定緩沖區(qū)所需的字節(jié)數(shù):DIM MYVARIABLE為點(diǎn)MyVariable.X = 100MyVariable.Y = 250DIM MyPointer作為IntPtr的Marshal.AllocHGlobal(Marshal.SizeOf(MYVARIABLE))Marshal.StructureToPtr(MYVARIABLE,MyPointer,假)
使用PtrToStructure方法扭轉(zhuǎn)的過程和讀從非托管內(nèi)存結(jié)構(gòu)。您可以使用此方法可以作為一個(gè)函數(shù)返回一個(gè)結(jié)構(gòu)的副本類型的基礎(chǔ)上,或填補(bǔ)了結(jié)構(gòu)參數(shù)作為一個(gè)子。請(qǐng)注意,PtrToStructure返回一個(gè)Object類型的引用,和Option Strict On時(shí),您必須轉(zhuǎn)換為結(jié)構(gòu)類型(例如,所使用的CType):作為點(diǎn)DIM MyPointMyPoint = CTYPE(Marshal.PtrToStructure(MyPointer的GetType(點(diǎn))),點(diǎn))復(fù)制方法
讀取和寫入陣列中的數(shù)據(jù),尤其是寶貴的,當(dāng)你需要二進(jìn)制數(shù)據(jù)流。 Copy方法讀取和寫入,根據(jù)您傳遞給它的參數(shù)。如果你想寫入數(shù)據(jù),你需要先分配一些緩沖區(qū)空間,就像你會(huì)使用字符串。接下來,您呼叫的復(fù)制方法,并通過數(shù)組本身,目的地址(IntPtr的分配),你要開始復(fù)制的元素的數(shù)組的索引,和緩沖區(qū)的大小:DIM MyData的(255)作為字節(jié)"在這里插入代碼,以填補(bǔ)字節(jié)數(shù)組DIM BufferAddress的IntPtr = Marshal.AllocHGlobal(256)Marshal.Copy(MYDATA,0,BufferAddress,256)
要閱讀從非托管內(nèi)存中的數(shù)組,調(diào)用復(fù)制的方法,并通過緩沖區(qū)的地址(IntPtr的),你想從緩沖區(qū)中的數(shù)據(jù)填充數(shù)組,數(shù)組的索引,你要開始復(fù)制到了,你要復(fù)制的數(shù)據(jù)的大小:MyData的DIM(255)以字節(jié) Marshal.Copy(BufferAddress,MYDATA,0,256)
Marshal類中有更多的方法,但他們大多是公用事業(yè)援助COM代碼進(jìn)行互操作。結(jié)論
這些功能也相當(dāng)有助于封送處理以及asnbsp管理的數(shù)據(jù); CopyMemory如非托管的內(nèi)存也被稱為RtlMoveMomry功能的一個(gè)很好的替代。
?
總結(jié)
以上是生活随笔為你收集整理的C#中Marshal 类的内存操作的一般功能概述的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Docker 环境:Nexus3.x 的
- 下一篇: elasticsearch-head 安