一見鐘情VB.NET指針
VB.NET有很多值得學(xué)習(xí)的地方,這里我們主要介紹VB.NET指針,包括介紹NET垃圾回收器等方面,欲知VB.NET如何。以下程序我們申請幾個指向不同類型的VB.NET指針:
- '使用<StructLayout(LayoutKind.Sequential)>屬性告訴net編譯器:結(jié)構(gòu)的元素在內(nèi)存中按其出現(xiàn)的順序排列
- <StructLayout(LayoutKind.Sequential)> _
- Public Structure DEFUDT_Test
- Public bytb As Byte
- Public i32a As Int32
- End Structure
- Public Function fnGetIntptr1() As IntPtr
- '取得一個4字節(jié)數(shù)組指針
- Dim tabytTest(3) As Byte
- '以下語句告訴net垃圾回收進程不對tabytTest進行處理,也就是說tabytTest占用的內(nèi)存區(qū)域固定不變。
- Dim thObject As GCHandleGCHandle = GCHandle.Alloc(tabytTest, GCHandleType.Pinned)
- Dim tpObject As IntPtr = thObject.AddrOfPinnedObject() '取得指向字節(jié)數(shù)組的指針
- '取得一個指向32位內(nèi)存數(shù)據(jù)的指針,
- '由于使用gchandle取指針的方法只能對引用的對象有效,
- '所以對如int32等值類型必須使用將其封裝成為一個對象的方法以變?yōu)橐妙愋?
- Dim ti32Test As Object = Convert.ToInt32(0)
- '以下語句告訴net垃圾回收進程不對ti32test進行處理,也就是說ti32Test的內(nèi)存位置固定不變。
- Dim thObject1 As GCHandleGCHandle = GCHandle.Alloc(ti32Test, GCHandleType.Pinned)
- Dim tpObject1 As IntPtr = thObject1.AddrOfPinnedObject() '取得ti32Test的首地址
- Dim tudtTest1 As DEFUDT_Test
- '由于結(jié)構(gòu)是一種值類型變量,為保證指針申請方便,我們申請
- '取得一個和結(jié)構(gòu)tudtTest1大小一致的字節(jié)數(shù)組指針,只要空間占用長度和結(jié)構(gòu)一樣就可以了
- '由于net在結(jié)構(gòu)封裝中會插入額外的數(shù)據(jù)位,所以一定要用sizeof方法得到結(jié)構(gòu)在非托管使用時的實際大小
- Dim tudtTest(Marshal.SizeOf(tudtTest1)) As Byte
- Dim thObject2 As GCHandleGCHandle = GCHandle.Alloc(tudtTest, GCHandleType.Pinned)
- Dim tpObject2 As IntPtr = thObject2.AddrOfPinnedObject() '取得指向結(jié)構(gòu)的指針
- '在這兒你可以寫對指針處理的任意代碼(在例2中會給予補充)……
- '在使用完畢后一定要釋放指針指向的內(nèi)存塊,讓垃圾回收器可對這個內(nèi)存塊回收處理
- If thObject.IsAllocated Then
- thObject.Free()
- End If
- If thObject1.IsAllocated Then
- thObject1.Free()
- End If
- If thObject2.IsAllocated Then
- thObject2.Free()
- End If
- End Function
上例中VB.NET指針流程處理可以歸納為:
1、定義一個具有合適內(nèi)存長度的引用變量(關(guān)于引用變量和值變量的差異可以參觀VB.NET的書籍)
2、使用GCHandle.Alloc方法將變量的內(nèi)存區(qū)域固定下來。
3、使用GCHandle對象的AddrOfPinnedObject取得該內(nèi)存區(qū)域的首地址并賦值給指針變量.
4、對指針進行操作
5、使用GCHandle對象的free方法釋放指針指向的內(nèi)存區(qū)域以便NET垃圾回收器可以回收這個內(nèi)存空間
6、VB.NET指針?biāo)赶驍?shù)據(jù)的存取
在.NET中,對指針指向數(shù)據(jù)的存儲函數(shù)都封裝在marshal類中,主要的函數(shù)包括:Copy、PtrToStringUni 、PtrToStructure 、OffsetOf、WriteXXX,RreadXXX等,其中WriteXXX的表示向指針?biāo)硎镜牡刂分袑懭隭XX類型的數(shù)據(jù),而ReadXXX中作用就是將VB.NET指針?biāo)诘刂返臄?shù)據(jù)以XXX類型方式讀出。
【編輯推薦】