Imports System
臺江網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)!從網(wǎng)頁設計、網(wǎng)站建設、微信開發(fā)、APP開發(fā)、自適應網(wǎng)站建設等網(wǎng)站項目制作,到程序開發(fā),運營維護。成都創(chuàng)新互聯(lián)成立與2013年到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設就選成都創(chuàng)新互聯(lián)。
Module Program
Sub Main()
Dim n As Integer
n=6
Console.WriteLine("{0}!={1}",n,fact(n))
n=10
For i As Integer=1 To n
Console.Write("{0}{1}",fibo(i),IIF(n=i,vbCrLf,","))
Next
Console.Write("按任意鍵繼續(xù)。。。 ")
Console.ReadKey(True)
End Sub
' 遞歸算階乘
Function fact(n As Long) As Long
If 0=n OrElse 1=n Then Return 1
Return n*fact(n-1)
End Function
' 遞歸算斐波那契數(shù)列
Function fibo(n As Long) As Long
If 1=n OrElse 2=n Then Return 1
Return fibo(n-1)+fibo(n-2)
End Function
End Module
例1:以下程序我們申請幾個指向不同類型的指針:
’使用StructLayout(LayoutKind.Sequential)屬性告訴net編譯器:結構的元素在內(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 GCHandle = GCHandle.Alloc(tabytTest, GCHandleType.Pinned)
Dim tpObject As IntPtr = thObject.AddrOfPinnedObject() ’取得指向字節(jié)數(shù)組的指針
’取得一個指向32位內(nèi)存數(shù)據(jù)的指針,
’由于使用gchandle取指針的方法只能對引用的對象有效,
’所以對如int32等值類型必須使用將其封裝成為一個對象的方法以變?yōu)橐妙愋?/p>
Dim ti32Test As Object = Convert.ToInt32(0)
’以下語句告訴net垃圾回收進程不對ti32test進行處理,也就是說ti32Test的內(nèi)存位置固定不變。
Dim thObject1 As GCHandle = GCHandle.Alloc(ti32Test, GCHandleType.Pinned)
Dim tpObject1 As IntPtr = thObject1.AddrOfPinnedObject() ’取得ti32Test的首地址
Dim tudtTest1 As DEFUDT_Test
’由于結構是一種值類型變量,為保證指針申請方便,我們申請
’取得一個和結構tudtTest1大小一致的字節(jié)數(shù)組指針,只要空間占用長度和結構一樣就可以了
’由于net在結構封裝中會插入額外的數(shù)據(jù)位,所以一定要用sizeof方法得到結構在非托管使用時的實際大小
Dim tudtTest(Marshal.SizeOf(tudtTest1)) As Byte
Dim thObject2 As GCHandle = GCHandle.Alloc(tudtTest, GCHandleType.Pinned)
Dim tpObject2 As IntPtr = thObject2.AddrOfPinnedObject() ’取得指向結構的指針
’在這兒你可以寫對指針處理的任意代碼(在例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
上例中指針流程處理可以歸納為:
1、 定義一個具有合適內(nèi)存長度的引用變量(關于引用變量和值變量的差異可以參觀VB.NET的書籍)
2、使用GCHandle.Alloc方法將變量的內(nèi)存區(qū)域固定下來。
3、使用GCHandle對象的AddrOfPinnedObject取得該內(nèi)存區(qū)域的首地址并賦值給指針變量.
4、對指針進行操作
5、使用GCHandle對象的free方法釋放指針指向的內(nèi)存區(qū)域以便net垃圾回收器可以回收這個內(nèi)存空間
2、指針所指向數(shù)據(jù)的存取
在點虐 中,對指針指向數(shù)據(jù)的存儲函數(shù)都封裝在marshal類中,主要的函數(shù)包括:Copy、PtrToStringUni 、PtrToStructure 、OffsetOf、WriteXXX,RreadXXX等,其中WriteXXX的表示向指針所表示的地址中寫入XXX類型的數(shù)據(jù),而ReadXXX中作用就是將指針所在地址的數(shù)據(jù)以XXX類型方式讀出??蠢?,我們使用這些方法演示對例1那幾個指向不同類型數(shù)據(jù)的指針作數(shù)據(jù)存/取操作。
例2:演示向例1申請得到的幾個指針執(zhí)行寫入及讀取數(shù)據(jù)的操作.
Marshal.WriteInt32(tpObject1, 0, Convert.ToInt32(77)) ’向ti32Test變量指向的地址寫入32位整數(shù)77
MsgBox("現(xiàn)在ti32Test的值為:" ti32Test) ’因為變量存儲地址的數(shù)據(jù)已改為77,所以顯示為77
’以下這句之所以可行,因為ti32Test是32位整數(shù),而tpObject指向的tabytTest數(shù)組剛好有4個元素
’而每一個byte元素都占用8位,合起來就是32位,和ti32Test占用的空間一樣。這就印證了前面提’
’到的net中指針沒有指向類型的說明。
Marshal.WriteInt32(tpObject, 0, ti32Test)
’以下代碼再將tabytTest字節(jié)數(shù)組的內(nèi)容理解為一個int32整數(shù),
’并將值賦值給tudtTest結構中的int32元素
’我們使用Marshal.OffsetOf(GetType(DEFUDT_Test), "i32a").ToInt32以取得i32a元素在結構中的內(nèi)存偏移位置
’所以New IntPtr(tpObject2.ToInt32 + Marshal.OffsetOf(GetType(DEFUDT_Test), "i32a").ToInt32)就臨時產(chǎn)生了
’一個指針并指向i32a所在的內(nèi)存地址(, 這個方法也說明了指針可以以字節(jié)為單位進行加減計算以指向合適的變量。
’Marshal.ReadInt32的作用是從指針中讀取一個32整數(shù)。
Marshal.WriteInt32(New IntPtr(tpObject2.ToInt32 + Marshal.OffsetOf(GetType(DEFUDT_Test), "i32a").ToInt32), _
0, Marshal.ReadInt32(tpObject))
’這兒可以將字節(jié)數(shù)組的內(nèi)容復制到真正的結構中
MsgBox(Marshal.OffsetOf(tudtTest1.GetType, "i32a").ToInt32)
tudtTest1 = CType(Marshal.PtrToStructure(tpObject2, GetType(DEFUDT_Test)), DEFUDT_Test)
MsgBox("結構tidtTest1中i32a元素的值為:" tudtTest1.i32a) ’此處將顯示剛賦的值77
啊 對 我忘了 打開文件的時候把得到的文件名放到這個變量里strFilename
是報錯還是出現(xiàn)什么問題 我測試過可以啊 因為圖片打開之后源文件是被使用的 所以我先拷貝了一個副本 再把原來的釋放掉 這樣才能刪除
要刪除到回收站好像沒有什么現(xiàn)成的方法,我用了API
Imports System.IO
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Public Class Viewer
Dim strFilename As String = String.Empty '存儲文件名
'定義一些API及所需常量、結構,刪除到回收站所需的,如需永久刪除文件則可以不定義
Public Const FO_DELETE As Integer = H3
Public Const FOF_NOCONFIRMATION As Short = H10
Public Const FOF_ALLOWUNDO As Short = H40
Declare Unicode Function SHFileOperation Lib "shell32.dll" ([In](), Out() ByVal sfo As SHFILEOPSTRUCT) As Int32
StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi) _
Public Class SHFILEOPSTRUCT
Public hwnd As IntPtr
Public wFunc As UInt32
Public pFrom As String
Public pTo As String
Public fFlags As UInt16
Public fAnyOperationsAborted As Int32
Public hNameMappings As IntPtr
Public lpszProgressTitle As String
End Class
'''''''''''''其他代碼''''''''''''''''''''
'刪除文件
Private Sub btnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelete.Click
If String.Empty = strFilename Then
Return
End If
If DialogResult.Yes = MessageBox.Show("是要刪除這個文件嗎?", "消息", MessageBoxButtons.YesNo, MessageBoxIcon.Information) Then
Dim bmp As Bitmap = New Bitmap(picView.Width, picView.Height)
Dim gra As Graphics = Graphics.FromImage(bmp)
gra.DrawImage(picView.Image, Point.Empty)
gra.Dispose()
picView.Image.Dispose()
picView.Image = bmp
Dim shfp As New SHFILEOPSTRUCT
With shfp
.wFunc = Convert.ToUInt32(FO_DELETE)
.pFrom = strFilename Chr(0)
.pTo = Nothing
.fFlags = Convert.ToUInt16(FOF_ALLOWUNDO Or FOF_NOCONFIRMATION)
End With
SHFileOperation(shfp)
btnDelete.Enabled = False
'以下一行永久刪除文件
'File.Delete(strFilename)
End If
End Sub
End Class